------------------------------------------------------------------------

r4235 | acceptthis | 2013-03-03 19:10:27 +0000 (Sun, 03 Mar 2013) | 5 lines

fix missing q2 surface water warp. fix missing q2 underwater warp.
tweak altwater shader+rendering to be capable of depth info too. Not enabling that yet.
fix q2 conchar colour issue.
fix rtlights in water.
attempt to remove borders of shadowmap lights. implement support for dynamic resolution shadowmaps. still needs to choose the resolution properly.
------------------------------------------------------------------------


git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4231 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2013-03-12 23:13:39 +00:00
parent eba3f5d4d1
commit de4a7409b2
18 changed files with 585 additions and 406 deletions

View File

@ -285,7 +285,6 @@ typedef struct dlight_s
} face [6];
int style; //multiply by style values if > 0
float fov; //spotlight
float dist;
struct dlight_s *next;
} dlight_t;

View File

@ -1826,6 +1826,7 @@ void CLQ2_CalcViewValues (void)
q2centity_t *ent;
q2frame_t *oldframe;
q2player_state_t *ps, *ops;
extern cvar_t gl_cshiftenabled;
r_refdef.useperspective = true;
@ -1900,8 +1901,9 @@ void CLQ2_CalcViewValues (void)
r_refdef.fov_x = ops->fov + lerp * (ps->fov - ops->fov);
// don't interpolate blend color
for (i=0 ; i<4 ; i++)
for (i=0 ; i<3 ; i++)
sw_blend[i] = ps->blend[i];
sw_blend[3] = ps->blend[3]*gl_cshiftenabled.value;
// add the weapon
CLQ2_AddViewWeapon (ps, ops);

View File

@ -1942,7 +1942,7 @@ void Surf_SetupFrame(void)
leaf = RMod_PointInLeaf (cl.worldmodel, r_origin);
r_viewcluster = r_viewcluster2 = leaf->cluster;
r_viewcontents = 0;//leaf->contents;
r_viewcontents = leaf->contents & (FTECONTENTS_LAVA|FTECONTENTS_SLIME|FTECONTENTS_WATER);
// check above and below so crossing solid water doesn't draw wrong
if (!leaf->contents)

View File

@ -158,7 +158,7 @@ void Skin_Find (player_info_t *sc)
*s = '\0';
#ifdef Q2CLIENT
if (cls.protocol == CP_QUAKE2)
model = Mod_ForName(va("players/%s/tris.mdl", name), false);
model = Mod_ForName(va("players/%s/tris.md2", name), false);
else
#endif
model = NULL;//Mod_ForName(va("models/players/%s.mdl", name), false);

View File

@ -1785,6 +1785,8 @@ void COM_Gamedir (const char *dir)
#define DMFCFG "set com_parseutf8 1\npm_airstep 1\nsv_demoExtensions 1\n"
/*set some stuff so our regular qw client appears more like hexen2*/
#define HEX2CFG "set com_parseutf8 -1\nset gl_font gfx/hexen2\nset in_builtinkeymap 0\nset_calc cl_playerclass int (random * 5) + 1\nset r_particlesdesc \"spikeset tsshaft h2part\"\nset sv_maxspeed 640\nset watervis 1\nset r_wateralpha 0.5\nset sv_pupglow 1\nset cl_model_bobbing 1\nsv_sound_land \"fx/thngland.wav\"\n"
/*yay q2!*/
#define Q2CFG "gl_font \":?col=0.44 1 0.2\"\n"
/*Q3's ui doesn't like empty model/headmodel/handicap cvars, even if the gamecode copes*/
#define Q3CFG "gl_overbright 2\nseta model sarge\nseta headmodel sarge\nseta handicap 100\n"
#define RMQCFG "sv_bigcoords 1\n"
@ -1825,7 +1827,7 @@ const gamemode_info_t gamemode_info[] = {
{"-portals", "h2mp", "FTE-H2MP", {"portals/hexen.rc",
"portals/pak3.pak"}, HEX2CFG,{"data1", "portals", "fteh2"}, "Hexen II MP"},
{"-hexen2", "hexen2", "FTE-Hexen2", {"data1/pak0.pak"}, HEX2CFG,{"data1", "fteh2"}, "Hexen II"},
{"-q2", "q2", "FTE-Quake2", {"baseq2/pak0.pak"}, NULL, {"baseq2", "fteq2"}, "Quake II"},
{"-q2", "q2", "FTE-Quake2", {"baseq2/pak0.pak"}, Q2CFG, {"baseq2", "fteq2"}, "Quake II"},
{"-q3", "q3", "FTE-Quake3", {"baseq3/pak0.pk3"}, Q3CFG, {"baseq3", "fteq3"}, "Quake III Arena"},
//can run in windows, needs

View File

@ -1221,7 +1221,7 @@ qboolean CMod_LoadTexInfo (lump_t *l) //yes I know these load from the same plac
if (out->flags & TI_SKY)
snprintf(sname, sizeof(sname), "sky/%s", in->texture);
else if (out->flags & (TI_WARP|TI_TRANS33|TI_TRANS66))
snprintf(sname, sizeof(sname), "%s%s/%s", ((out->flags&TI_WARP)?"warp":"trans"), ((out->flags&TI_TRANS66)?"66":(out->flags&TI_TRANS33?"33":"")), in->texture);
snprintf(sname, sizeof(sname), "%s/%s#ALPHA=%s", ((out->flags&TI_WARP)?"warp":"trans"), in->texture, ((out->flags&TI_TRANS66)?"0.66":(out->flags&TI_TRANS33?"0.33":"1")));
else
snprintf(sname, sizeof(sname), "wall/%s", in->texture);

View File

@ -70,7 +70,6 @@ enum
extern cvar_t r_glsl_offsetmapping, r_noportals;
static void BE_SendPassBlendDepthMask(unsigned int sbits);
void GLBE_RenderToTexture(texid_t sourcecol, texid_t sourcedepth, texid_t destcol, qboolean usedepth);
void GLBE_SubmitBatch(batch_t *batch);
static qboolean GLBE_RegisterLightShader(int mode);
@ -103,6 +102,7 @@ struct {
int fbo_reflection;
texid_t tex_reflection; /*basically a portal rendered to texture*/
texid_t tex_refraction; /*the (culled) underwater view*/
texid_t tex_refractiondepth; /*the (culled) underwater view*/
texid_t tex_ripplemap; /*temp image for waves and things.*/
qboolean force2d;
@ -184,6 +184,7 @@ struct {
texid_t lighttexture;
texid_t lightcubemap;
float lightprojmatrix[16]; /*world space*/
vec4_t lightshadowmapinfo;
};
int wbatch;
@ -940,8 +941,13 @@ void R_IBrokeTheArrays(void)
#ifdef RTLIGHTS
//called from gl_shadow
void GLBE_SetupForShadowMap(texid_t shadowmaptex)
void GLBE_SetupForShadowMap(texid_t shadowmaptex, int texwidth, int texheight, float shadowscale)
{
shaderstate.lightshadowmapinfo[0] = 1.0/texwidth;
shaderstate.lightshadowmapinfo[1] = 1.0/texwidth;
shaderstate.lightshadowmapinfo[2] = 1.0;
shaderstate.lightshadowmapinfo[3] = shadowscale;
shaderstate.curshadowmap = shadowmaptex;
while(shaderstate.lastpasstmus>0)
{
@ -1101,6 +1107,9 @@ static void Shader_BindTextureForPass(int tmu, const shaderpass_t *pass)
}
t = shaderstate.tex_refraction;
break;
case T_GEN_REFRACTIONDEPTH:
t = shaderstate.tex_refractiondepth;
break;
case T_GEN_RIPPLEMAP:
t = shaderstate.tex_ripplemap;
break;
@ -2893,6 +2902,9 @@ static void BE_Program_Set_Attributes(const program_t *prog, unsigned int perm,
qglUniformMatrix4fvARB(ph, 1, false, t);
}
break;
case SP_LIGHTSHADOWMAPINFO:
qglUniform4fvARB(ph, 1, shaderstate.lightshadowmapinfo);
break;
/*static lighting info*/
case SP_E_L_DIR:
@ -3882,7 +3894,7 @@ static void GLBE_SubmitMeshesSortList(batch_t *sortlist)
if ((batch->shader->flags & SHADER_HASREFLECT) && gl_config.ext_framebuffer_objects)
{
vrect_t orect = r_refdef.vrect;
vrect_t orect = r_refdef.vrect, oprect = r_refdef.pxrect;
if (!shaderstate.tex_reflection.num)
{
shaderstate.tex_reflection = GL_AllocNewTexture("***tex_reflection***", vid.pixelwidth/2, vid.pixelheight/2, 0);
@ -3894,25 +3906,32 @@ static void GLBE_SubmitMeshesSortList(batch_t *sortlist)
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
GL_ForceDepthWritable();
GLBE_RenderToTexture(r_nulltex, r_nulltex, shaderstate.tex_reflection, true);
GLBE_RenderToTexture(r_nulltex, r_nulltex, shaderstate.tex_reflection, r_nulltex, true);
qglViewport (0, 0, vid.pixelwidth/2, vid.pixelheight/2);
r_refdef.vrect.x = 0;
r_refdef.vrect.y = 0;
r_refdef.vrect.width = vid.width/2;
r_refdef.vrect.height = vid.height/2;
r_refdef.pxrect.x = 0;
r_refdef.pxrect.width = vid.pixelwidth/2;
r_refdef.pxrect.height = vid.pixelheight/2;
r_refdef.pxrect.y = r_refdef.pxrect.height;
GL_ForceDepthWritable();
qglClearColor(0, 0, 0, 0);
qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
GLR_DrawPortal(batch, cl.worldmodel->batches, 1);
GLBE_RenderToTexture(r_nulltex, r_nulltex, r_nulltex, false);
GLBE_RenderToTexture(r_nulltex, r_nulltex, r_nulltex, r_nulltex, false);
qglViewport (0, 0, vid.pixelwidth, vid.pixelheight);
r_refdef.vrect = orect;
r_refdef.pxrect = oprect;
}
if (batch->shader->flags & SHADER_HASREFRACT)
if (batch->shader->flags & (SHADER_HASREFRACT|SHADER_HASREFRACTDEPTH))
{
if (r_refract_fboival)
{
vrect_t orect;
vrect_t ovrect = r_refdef.vrect, oprect = r_refdef.pxrect;
GL_ForceDepthWritable();
if (!shaderstate.tex_refraction.num)
{
shaderstate.tex_refraction = GL_AllocNewTexture("***tex_refraction***", vid.pixelwidth/2, vid.pixelheight/2, 0);
@ -3923,31 +3942,49 @@ static void GLBE_SubmitMeshesSortList(batch_t *sortlist)
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
GL_ForceDepthWritable();
GLBE_RenderToTexture(r_nulltex, r_nulltex, shaderstate.tex_refraction, true);
if (batch->shader->flags & SHADER_HASREFRACTDEPTH)
{
if (!shaderstate.tex_refractiondepth.num)
{
shaderstate.tex_refractiondepth = GL_AllocNewTexture("***tex_refractiondepth***", vid.pixelwidth/2, vid.pixelheight/2, 0);
GL_MTBind(0, GL_TEXTURE_2D, shaderstate.tex_refractiondepth);
qglTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24_ARB, vid.pixelwidth/2, vid.pixelheight/2, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
GLBE_RenderToTexture(r_nulltex, r_nulltex, shaderstate.tex_refraction, shaderstate.tex_refractiondepth, true);
}
else
GLBE_RenderToTexture(r_nulltex, r_nulltex, shaderstate.tex_refraction, r_nulltex, true);
qglViewport (0, 0, vid.pixelwidth/2, vid.pixelheight/2);
orect = r_refdef.vrect;
r_refdef.vrect.x = 0;
r_refdef.vrect.y = 0;
r_refdef.vrect.width = vid.width/2;
r_refdef.vrect.height = vid.height/2;
r_refdef.pxrect.x = 0;
r_refdef.pxrect.width = vid.pixelwidth/2;
r_refdef.pxrect.height = vid.pixelheight/2;
r_refdef.pxrect.y = r_refdef.pxrect.height;
GL_ForceDepthWritable();
qglClearColor(0, 0, 0, 0);
qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
GLR_DrawPortal(batch, cl.worldmodel->batches, 2);
GLBE_RenderToTexture(r_nulltex, r_nulltex, r_nulltex, false);
GLR_DrawPortal(batch, cl.worldmodel->batches, ((batch->shader->flags & SHADER_HASREFRACTDEPTH)?3:2)); //fixme
GLBE_RenderToTexture(r_nulltex, r_nulltex, r_nulltex, r_nulltex, false);
qglViewport (0, 0, vid.pixelwidth, vid.pixelheight);
r_refdef.vrect = orect;
r_refdef.vrect = ovrect;
r_refdef.pxrect = oprect;
}
else
GLR_DrawPortal(batch, cl.worldmodel->batches, 3);
}
if ((batch->shader->flags & SHADER_HASRIPPLEMAP) && gl_config.ext_framebuffer_objects)
{
vrect_t orect;
vrect_t orect = r_refdef.vrect, oprect = r_refdef.pxrect;
if (!shaderstate.tex_ripplemap.num)
{
shaderstate.tex_ripplemap = GL_AllocNewTexture("***tex_ripplemap***", vid.pixelwidth/2, vid.pixelheight/2, 0);
@ -3958,13 +3995,16 @@ static void GLBE_SubmitMeshesSortList(batch_t *sortlist)
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
GLBE_RenderToTexture(r_nulltex, r_nulltex, shaderstate.tex_ripplemap, false);
GLBE_RenderToTexture(r_nulltex, r_nulltex, shaderstate.tex_ripplemap, r_nulltex, false);
qglViewport (0, 0, vid.pixelwidth/2, vid.pixelheight/2);
orect = r_refdef.vrect;
r_refdef.vrect.x = 0;
r_refdef.vrect.y = 0;
r_refdef.vrect.width = vid.width/2;
r_refdef.vrect.height = vid.height/2;
r_refdef.pxrect.x = 0;
r_refdef.pxrect.width = vid.pixelwidth/2;
r_refdef.pxrect.height = vid.pixelheight/2;
r_refdef.pxrect.y = r_refdef.pxrect.height;
qglClearColor(0, 0, 0, 0);
qglClear(GL_COLOR_BUFFER_BIT);
@ -3974,10 +4014,11 @@ static void GLBE_SubmitMeshesSortList(batch_t *sortlist)
r_refdef.recurse = true; //paranoid, should stop potential infinite loops
GLBE_SubmitMeshes(true, SHADER_SORT_RIPPLE, SHADER_SORT_RIPPLE);
r_refdef.recurse = false;
GLBE_RenderToTexture(r_nulltex, r_nulltex, r_nulltex, false);
GLBE_RenderToTexture(r_nulltex, r_nulltex, r_nulltex, r_nulltex, false);
qglViewport (0, 0, vid.pixelwidth, vid.pixelheight);
r_refdef.vrect = orect;
r_refdef.pxrect = oprect;
}
BE_SelectMode(oldbem);
}
@ -4084,7 +4125,7 @@ void GLBE_BaseEntTextures(void)
}
#endif
void GLBE_RenderToTexture(texid_t sourcecol, texid_t sourcedepth, texid_t destcol, qboolean usedepth)
void GLBE_RenderToTexture(texid_t sourcecol, texid_t sourcedepth, texid_t destcol, texid_t destdepth, qboolean usedepth)
{
shaderstate.tex_sourcecol = sourcecol;
shaderstate.tex_sourcedepth = sourcedepth;
@ -4109,11 +4150,12 @@ void GLBE_RenderToTexture(texid_t sourcecol, texid_t sourcedepth, texid_t destco
}
else
{
qglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24_ARB, vid.pixelwidth/2, vid.pixelheight/2);
qglGenRenderbuffersEXT(1, &shaderstate.rb_stencil);
qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, shaderstate.rb_stencil);
qglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX8_EXT, vid.pixelwidth/2, vid.pixelheight/2);
qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, shaderstate.rb_stencil);
qglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24_ARB, vid.pixelwidth/2, vid.pixelheight/2);
}
qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, shaderstate.rb_depth);
@ -4122,6 +4164,11 @@ void GLBE_RenderToTexture(texid_t sourcecol, texid_t sourcedepth, texid_t destco
}
else
qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, shaderstate.fbo_diffuse);
if (destdepth.num)
qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, destdepth.num, 0);
else
qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, shaderstate.rb_depth);
}
else
{
@ -4303,6 +4350,11 @@ void GLBE_DrawWorld (qboolean drawworld, qbyte *vis)
R_DestroyTexture(shaderstate.tex_refraction);
shaderstate.tex_refraction = r_nulltex;
}
if (shaderstate.tex_refractiondepth.num)
{
R_DestroyTexture(shaderstate.tex_refractiondepth);
shaderstate.tex_refractiondepth = r_nulltex;
}
if (shaderstate.temptexture.num)
{
R_DestroyTexture(shaderstate.temptexture);

View File

@ -60,8 +60,6 @@ static int texwidth[MAXLEVELS], texheight[MAXLEVELS];
void GLBE_RenderToTexture(texid_t sourcecol, texid_t sourcedepth, texid_t destcol, qboolean usedepth);
void R_BloomRegister(void)
{
Cvar_Register (&r_bloom, "bloom");
@ -194,13 +192,13 @@ void R_BloomBlend (void)
qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_refdef.pxrect.x, r_refdef.pxrect.y - r_refdef.pxrect.height, r_refdef.pxrect.width, r_refdef.pxrect.height);
/*filter the screen into a downscaled image*/
GLBE_RenderToTexture(scrtex, r_nulltex, pingtex[0][0], false);
GLBE_RenderToTexture(scrtex, r_nulltex, pingtex[0][0], r_nulltex, false);
qglViewport (0, 0, texwidth[0], texheight[0]);
R2D_ScalePic(0, vid.height, vid.width, -(int)vid.height, bloomfilter);
/*and downscale that multiple times*/
for (i = 1; i < MAXLEVELS; i++)
{
GLBE_RenderToTexture(pingtex[0][i-1], r_nulltex, pingtex[0][i], false);
GLBE_RenderToTexture(pingtex[0][i-1], r_nulltex, pingtex[0][i], r_nulltex, false);
qglViewport (0, 0, texwidth[i], texheight[i]);
R2D_ScalePic(0, vid.height, vid.width, -(int)vid.height, bloomrescale);
}
@ -211,7 +209,7 @@ void R_BloomBlend (void)
/*must be 1.2th of a pixel*/
r_worldentity.glowmod[0] = 1.2 / texwidth[i];
r_worldentity.glowmod[1] = 0;
GLBE_RenderToTexture(pingtex[0][i], r_nulltex, pingtex[1][i], false);
GLBE_RenderToTexture(pingtex[0][i], r_nulltex, pingtex[1][i], r_nulltex, false);
qglViewport (0, 0, texwidth[i], texheight[i]);
R2D_ScalePic(0, vid.height, vid.width, -(int)vid.height, bloomblur);
}
@ -219,7 +217,7 @@ void R_BloomBlend (void)
{
r_worldentity.glowmod[0] = 0;
r_worldentity.glowmod[1] = 1.2 / texheight[i];
GLBE_RenderToTexture(pingtex[1][i], r_nulltex, pingtex[0][i], false);
GLBE_RenderToTexture(pingtex[1][i], r_nulltex, pingtex[0][i], r_nulltex, false);
qglViewport (0, 0, texwidth[i], texheight[i]);
R2D_ScalePic(0, vid.height, vid.width, -(int)vid.height, bloomblur);
}
@ -227,7 +225,7 @@ void R_BloomBlend (void)
GL_Set2D(false);
/*combine them onto the screen*/
GLBE_RenderToTexture(scrtex, r_nulltex, r_nulltex, false);
GLBE_RenderToTexture(scrtex, r_nulltex, r_nulltex, r_nulltex, false);
R2D_ScalePic(r_refdef.vrect.x, r_refdef.vrect.y + r_refdef.vrect.height, r_refdef.vrect.width, -r_refdef.vrect.height, bloomfinal);
}
void R_InitBloomTextures(void)

View File

@ -194,6 +194,7 @@ typedef struct font_s
void *membuf;
#endif
struct font_s *alt;
vec3_t alttint;
} font_t;
typedef struct {
@ -962,6 +963,8 @@ struct font_s *Font_LoadFont(int vheight, char *fontfilename)
f->charheight = height;
Q_strncpyz(f->name, fontfilename, sizeof(f->name));
VectorSet(f->alttint, 1.16, 0.54, 0.41);
#ifdef DOOMWADS
if (!*fontfilename)
{
@ -1087,7 +1090,17 @@ struct font_s *Font_LoadFont(int vheight, char *fontfilename)
if (aname)
{
*aname = 0;
f->alt = Font_LoadFont(vheight, aname+1);
if (!strncmp(aname+1, "?col=", 5))
{
char *t = aname+6;
f->alttint[0] = strtod(t, &t);
if (*t == ' ') t++;
f->alttint[1] = strtod(t, &t);
if (*t == ' ') t++;
f->alttint[2] = strtod(t, &t);
}
else
f->alt = Font_LoadFont(vheight, aname+1);
}
if (!Font_LoadFreeTypeFont(f, height, fontfilename))
{
@ -1507,9 +1520,9 @@ int Font_DrawChar(int px, int py, unsigned int charcode)
if (charcode & CON_2NDCHARSETTEXT)
{
font_forecolour[0] = min(font_forecolour[0]*1.16, 255);
font_forecolour[1] *= 0.54;
font_forecolour[2] *= 0.41;
font_forecolour[0] = min(font_forecolour[0]*font->alttint[0], 255);
font_forecolour[1] = min(font_forecolour[1]*font->alttint[1], 255);
font_forecolour[2] = min(font_forecolour[2]*font->alttint[2], 255);
}
}
}
@ -1678,9 +1691,9 @@ float Font_DrawScaleChar(float px, float py, unsigned int charcode)
if (charcode & CON_2NDCHARSETTEXT)
{
font_forecolour[0] = min(font_forecolour[0]*1.16, 255);
font_forecolour[1] *= 0.54;
font_forecolour[2] *= 0.41;
font_forecolour[0] = min(font_forecolour[0]*font->alttint[0], 255);
font_forecolour[1] = min(font_forecolour[1]*font->alttint[1], 255);
font_forecolour[2] = min(font_forecolour[2]*font->alttint[2], 255);
}
}
}

View File

@ -153,8 +153,8 @@ void GL_SetupSceneProcessingTextures (void)
if (!gl_config.arb_shader_objects)
return;
TEXASSIGN(scenepp_texture_warp, GL_AllocNewTexture("***postprocess_warp***", PP_WARP_TEX_SIZE, PP_WARP_TEX_SIZE, 0));
TEXASSIGN(scenepp_texture_edge, GL_AllocNewTexture("***postprocess_edge***", PP_WARP_TEX_SIZE, PP_WARP_TEX_SIZE, 0));
TEXASSIGN(scenepp_texture_warp, GL_AllocNewTexture("***postprocess_warp***", PP_WARP_TEX_SIZE, PP_WARP_TEX_SIZE, IF_NOMIPMAP|IF_NOGAMMA));
TEXASSIGN(scenepp_texture_edge, GL_AllocNewTexture("***postprocess_edge***", PP_WARP_TEX_SIZE, PP_WARP_TEX_SIZE, IF_NOMIPMAP|IF_NOGAMMA));
// init warp texture - this specifies offset in
for (y=0; y<PP_WARP_TEX_SIZE; y++)
@ -197,7 +197,7 @@ void GL_SetupSceneProcessingTextures (void)
{
fx = (PP_AMP_TEX_SIZE - (float)x) / PP_AMP_TEX_BORDER;
}
if (y < PP_AMP_TEX_BORDER)
{
fy = (float)y / PP_AMP_TEX_BORDER;
@ -207,17 +207,21 @@ void GL_SetupSceneProcessingTextures (void)
fy = (PP_AMP_TEX_SIZE - (float)y) / PP_AMP_TEX_BORDER;
}
if (fx < fy)
{
fy = fx;
}
//avoid any sudden changes.
fx=sin(fx*M_PI*0.5);
fy=sin(fy*M_PI*0.5);
pp_edge_tex[i ] = fy * 255;
pp_edge_tex[i+1] = 0;
//lame
fx = fy = min(fx, fy);
pp_edge_tex[i ] = fx * 255;
pp_edge_tex[i+1] = fy * 255;
pp_edge_tex[i+2] = 0;
}
}
// scenepp_texture_edge = R_LoadTexture32("***postprocess_edge***", PP_AMP_TEX_SIZE, PP_AMP_TEX_SIZE, pp_edge_tex, IF_NOMIPMAP|IF_NOGAMMA|IF_NOPICMIP);
GL_MTBind(0, GL_TEXTURE_2D, scenepp_texture_edge);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
@ -420,6 +424,8 @@ void R_SetupGL (float stereooffset)
#ifdef RTLIGHTS
stencilshadows |= r_shadow_realtime_dlight.ival && r_shadow_realtime_dlight_shadows.ival;
stencilshadows |= r_shadow_realtime_world.ival && r_shadow_realtime_world_shadows.ival;
//if (r_shadow_shadowmapping.ival)
stencilshadows = false;
#endif
if ((!stencilshadows || !gl_stencilbits) && gl_maxdist.value>=100)//gl_nv_range_clamp)
@ -1058,7 +1064,6 @@ void GLR_SetupFog (void)
}
#endif
void GLBE_RenderToTexture(texid_t sourcecol, texid_t sourcedepth, texid_t destcol, qboolean usedepth);
static void R_RenderMotionBlur(void)
{
int vwidth = 1, vheight = 1;
@ -1097,10 +1102,10 @@ static void R_RenderMotionBlur(void)
"}\n"
"}\n"
);
GLBE_RenderToTexture(sceneblur_texture, r_nulltex, r_nulltex, false);
GLBE_RenderToTexture(sceneblur_texture, r_nulltex, r_nulltex, r_nulltex, false);
R2D_ImageColours(1, 1, 1, gl_motionblur.value);
R2D_Image(0, 0, vid.width, vid.height, cs-vs, ct+vt, cs+vs, ct-vt, shader);
GLBE_RenderToTexture(r_nulltex, r_nulltex, r_nulltex, false);
GLBE_RenderToTexture(r_nulltex, r_nulltex, r_nulltex, r_nulltex, false);
//grab the current image so we can feed that back into the next frame.
GL_MTBind(0, GL_TEXTURE_2D, sceneblur_texture);

View File

@ -169,7 +169,26 @@ skipwhite:
return com_token;
}
static float Shader_FloatArgument(shader_t *shader, char *arg)
{
char *var;
int arglen = strlen(arg);
//grab an argument instead, otherwise 0
var = shader->name;
while(var = strchr(var, '#'))
{
if (!strnicmp(var, arg, arglen))
{
if (var[arglen] == '=')
return strtod(var+arglen+1, NULL);
if (var[arglen] == '#' || !var[arglen])
return 1; //present, but no value
}
var++;
}
return 0; //not present.
}
@ -207,11 +226,10 @@ void *shader_active_hash_mem;
//static float r_skyheight;
char *Shader_Skip( char *ptr );
static qboolean Shader_Parsetok( shader_t *shader, shaderpass_t *pass, shaderkey_t *keys,
char *token, char **ptr );
static void Shader_ParseFunc( char **args, shaderfunc_t *func );
static void Shader_MakeCache( char *path );
static void Shader_GetPathAndOffset( char *name, char **path, unsigned int *offset );
static qboolean Shader_Parsetok(shader_t *shader, shaderpass_t *pass, shaderkey_t *keys, char *token, char **ptr);
static void Shader_ParseFunc(shader_t *shader, char **args, shaderfunc_t *func);
static void Shader_MakeCache(char *path);
static void Shader_GetPathAndOffset(char *name, char **path, unsigned int *offset);
static void Shader_ReadShader(shader_t *s, char *shadersource, int parsemode);
//===========================================================================
@ -230,24 +248,26 @@ static qboolean Shader_EvaluateCondition(shader_t *shader, char **ptr)
if (*token == '$')
{
token++;
if (!Q_stricmp(token, "lpp"))
if (*token == '#')
conditiontrue = conditiontrue == !!Shader_FloatArgument(shader, token);
else if (!Q_stricmp(token, "lpp"))
conditiontrue = conditiontrue == r_lightprepass.ival;
else if (!Q_stricmp(token, "lightmap"))
conditiontrue = conditiontrue == !r_fullbright.value;
else if (!Q_stricmp(token, "deluxmap") )
else if (!Q_stricmp(token, "deluxmap"))
conditiontrue = conditiontrue == r_deluxemapping.ival;
//normalmaps are generated if they're not already known.
else if (!Q_stricmp(token, "normalmap") )
else if (!Q_stricmp(token, "normalmap"))
conditiontrue = conditiontrue == r_loadbumpmapping;
else if (!Q_stricmp(token, "opengl") )
else if (!Q_stricmp(token, "opengl"))
conditiontrue = conditiontrue == (qrenderer == QR_OPENGL);
else if (!Q_stricmp(token, "d3d9") )
else if (!Q_stricmp(token, "d3d9"))
conditiontrue = conditiontrue == (qrenderer == QR_DIRECT3D9);
else if (!Q_stricmp(token, "d3d11") )
else if (!Q_stricmp(token, "d3d11"))
conditiontrue = conditiontrue == (qrenderer == QR_DIRECT3D11);
else if (!Q_stricmp(token, "gles") )
else if (!Q_stricmp(token, "gles"))
{
#ifdef GLQUAKE
conditiontrue = conditiontrue == ((qrenderer == QR_OPENGL) && !!gl_config.gles);
@ -255,7 +275,7 @@ static qboolean Shader_EvaluateCondition(shader_t *shader, char **ptr)
conditiontrue = conditiontrue == false;
#endif
}
else if (!Q_stricmp(token, "nofixed") )
else if (!Q_stricmp(token, "nofixed"))
{
switch(qrenderer)
{
@ -274,7 +294,7 @@ static qboolean Shader_EvaluateCondition(shader_t *shader, char **ptr)
break;
}
}
else if (!Q_stricmp(token, "glsl") )
else if (!Q_stricmp(token, "glsl"))
{
#ifdef GLQUAKE
conditiontrue = conditiontrue == ((qrenderer == QR_OPENGL) && gl_config.arb_shader_objects);
@ -282,7 +302,7 @@ static qboolean Shader_EvaluateCondition(shader_t *shader, char **ptr)
conditiontrue = conditiontrue == false;
#endif
}
else if (!Q_stricmp(token, "hlsl") )
else if (!Q_stricmp(token, "hlsl"))
{
switch(qrenderer)
{
@ -301,11 +321,11 @@ static qboolean Shader_EvaluateCondition(shader_t *shader, char **ptr)
break;
}
}
else if (!Q_stricmp(token, "haveprogram") )
else if (!Q_stricmp(token, "haveprogram"))
{
conditiontrue = conditiontrue == !!shader->prog;
}
else if (!Q_stricmp(token, "programs") )
else if (!Q_stricmp(token, "programs"))
{
switch(qrenderer)
{
@ -329,15 +349,15 @@ static qboolean Shader_EvaluateCondition(shader_t *shader, char **ptr)
break;
}
}
else if (!Q_stricmp(token, "diffuse") )
else if (!Q_stricmp(token, "diffuse"))
conditiontrue = conditiontrue == true;
else if (!Q_stricmp(token, "specular") )
else if (!Q_stricmp(token, "specular"))
conditiontrue = conditiontrue == false;
else if (!Q_stricmp(token, "fullbright") )
else if (!Q_stricmp(token, "fullbright"))
conditiontrue = conditiontrue == false;
else if (!Q_stricmp(token, "topoverlay") )
else if (!Q_stricmp(token, "topoverlay"))
conditiontrue = conditiontrue == false;
else if (!Q_stricmp(token, "loweroverlay") )
else if (!Q_stricmp(token, "loweroverlay"))
conditiontrue = conditiontrue == false;
else
{
@ -396,27 +416,23 @@ static char *Shader_ParseExactString(char **ptr)
{
char *token;
if ( !ptr || !(*ptr) ) {
if (!ptr || !(*ptr))
return "";
}
if ( !**ptr || **ptr == '}' ) {
if (!**ptr || **ptr == '}')
return "";
}
token = COM_ParseExt(ptr, false, false);
return token;
}
static char *Shader_ParseString ( char **ptr )
static char *Shader_ParseString(char **ptr)
{
char *token;
if ( !ptr || !(*ptr) ) {
if (!ptr || !(*ptr))
return "";
}
if ( !**ptr || **ptr == '}' ) {
if (!**ptr || **ptr == '}')
return "";
}
token = COM_ParseExt(ptr, false, true);
Q_strlwr ( token );
@ -424,52 +440,53 @@ static char *Shader_ParseString ( char **ptr )
return token;
}
static char *Shader_ParseSensString ( char **ptr )
static char *Shader_ParseSensString(char **ptr)
{
char *token;
if ( !ptr || !(*ptr) ) {
if (!ptr || !(*ptr))
return "";
}
if ( !**ptr || **ptr == '}' ) {
if (!**ptr || **ptr == '}')
return "";
}
token = COM_ParseExt(ptr, false, true);
return token;
}
static float Shader_ParseFloat(char **ptr)
static float Shader_ParseFloat(shader_t *shader, char **ptr)
{
char *token;
if (!ptr || !(*ptr))
{
return 0;
}
if (!**ptr || **ptr == '}')
{
return 0;
}
token = COM_ParseExt(ptr, false, true);
if (*token == '$')
{
cvar_t *var;
var = Cvar_FindVar(token+1);
if (var)
return var->value;
if (token[1] == '#')
{
return Shader_FloatArgument(shader, token+1);
}
else
{
cvar_t *var;
var = Cvar_FindVar(token+1);
if (var)
return var->value;
}
}
return atof(token);
}
static void Shader_ParseVector ( char **ptr, vec3_t v )
static void Shader_ParseVector(shader_t *shader, char **ptr, vec3_t v)
{
char *scratch;
char *token;
qboolean bracket;
token = Shader_ParseString ( ptr );
token = Shader_ParseString(ptr);
if (*token == '$')
{
cvar_t *var;
@ -485,20 +502,23 @@ static void Shader_ParseVector ( char **ptr, vec3_t v )
ptr = &scratch;
scratch = var->string;
token = Shader_ParseString ( ptr );
token = Shader_ParseString( ptr);
}
if ( !Q_stricmp (token, "(") ) {
if (!Q_stricmp (token, "("))
{
bracket = true;
token = Shader_ParseString ( ptr );
} else if ( token[0] == '(' ) {
token = Shader_ParseString(ptr);
}
else if (token[0] == '(')
{
bracket = true;
token = &token[1];
} else {
bracket = false;
}
else
bracket = false;
v[0] = atof ( token );
v[1] = Shader_ParseFloat ( ptr );
v[1] = Shader_ParseFloat (shader, ptr );
token = Shader_ParseString ( ptr );
if ( !token[0] ) {
@ -582,29 +602,28 @@ qboolean Shader_ParseSkySides (char *shadername, char *texturename, texid_t *ima
return allokay;
}
static void Shader_ParseFunc ( char **ptr, shaderfunc_t *func )
static void Shader_ParseFunc (shader_t *shader, char **ptr, shaderfunc_t *func)
{
char *token;
token = Shader_ParseString ( ptr );
if ( !Q_stricmp (token, "sin") ) {
token = Shader_ParseString (ptr);
if (!Q_stricmp (token, "sin"))
func->type = SHADER_FUNC_SIN;
} else if ( !Q_stricmp (token, "triangle") ) {
else if (!Q_stricmp (token, "triangle"))
func->type = SHADER_FUNC_TRIANGLE;
} else if ( !Q_stricmp (token, "square") ) {
else if (!Q_stricmp (token, "square"))
func->type = SHADER_FUNC_SQUARE;
} else if ( !Q_stricmp (token, "sawtooth") ) {
else if (!Q_stricmp (token, "sawtooth"))
func->type = SHADER_FUNC_SAWTOOTH;
} else if (!Q_stricmp (token, "inversesawtooth") ) {
else if (!Q_stricmp (token, "inversesawtooth"))
func->type = SHADER_FUNC_INVERSESAWTOOTH;
} else if (!Q_stricmp (token, "noise") ) {
else if (!Q_stricmp (token, "noise"))
func->type = SHADER_FUNC_NOISE;
}
func->args[0] = Shader_ParseFloat ( ptr );
func->args[1] = Shader_ParseFloat ( ptr );
func->args[2] = Shader_ParseFloat ( ptr );
func->args[3] = Shader_ParseFloat ( ptr );
func->args[0] = Shader_ParseFloat (shader, ptr);
func->args[1] = Shader_ParseFloat (shader, ptr);
func->args[2] = Shader_ParseFloat (shader, ptr);
func->args[3] = Shader_ParseFloat (shader, ptr);
}
//===========================================================================
@ -697,46 +716,52 @@ static void Shader_DeformVertexes ( shader_t *shader, shaderpass_t *pass, char *
char *token;
deformv_t *deformv;
if ( shader->numdeforms >= SHADER_DEFORM_MAX ) {
if ( shader->numdeforms >= SHADER_DEFORM_MAX )
return;
}
deformv = &shader->deforms[shader->numdeforms];
token = Shader_ParseString ( ptr );
if ( !Q_stricmp (token, "wave") ) {
if ( !Q_stricmp (token, "wave") )
{
deformv->type = DEFORMV_WAVE;
deformv->args[0] = Shader_ParseFloat ( ptr );
if ( deformv->args[0] ) {
deformv->args[0] = Shader_ParseFloat (shader, ptr);
if (deformv->args[0])
deformv->args[0] = 1.0f / deformv->args[0];
}
Shader_ParseFunc ( ptr, &deformv->func );
} else if ( !Q_stricmp (token, "normal") ) {
Shader_ParseFunc (shader, ptr, &deformv->func );
}
else if ( !Q_stricmp (token, "normal") )
{
deformv->type = DEFORMV_NORMAL;
deformv->args[0] = Shader_ParseFloat ( ptr );
deformv->args[1] = Shader_ParseFloat ( ptr );
} else if ( !Q_stricmp (token, "bulge") ) {
deformv->args[0] = Shader_ParseFloat (shader, ptr );
deformv->args[1] = Shader_ParseFloat (shader, ptr );
}
else if ( !Q_stricmp (token, "bulge") )
{
deformv->type = DEFORMV_BULGE;
Shader_ParseVector ( ptr, deformv->args );
Shader_ParseVector (shader, ptr, deformv->args );
shader->flags |= SHADER_DEFORMV_BULGE;
} else if ( !Q_stricmp (token, "move") ) {
}
else if ( !Q_stricmp (token, "move") )
{
deformv->type = DEFORMV_MOVE;
Shader_ParseVector ( ptr, deformv->args );
Shader_ParseFunc ( ptr, &deformv->func );
} else if ( !Q_stricmp (token, "autosprite") ) {
Shader_ParseVector (shader, ptr, deformv->args );
Shader_ParseFunc (shader, ptr, &deformv->func );
}
else if ( !Q_stricmp (token, "autosprite") )
{
deformv->type = DEFORMV_AUTOSPRITE;
shader->flags |= SHADER_AUTOSPRITE;
} else if ( !Q_stricmp (token, "autosprite2") ) {
}
else if ( !Q_stricmp (token, "autosprite2") )
{
deformv->type = DEFORMV_AUTOSPRITE2;
shader->flags |= SHADER_AUTOSPRITE;
} else if ( !Q_stricmp (token, "projectionShadow") ) {
deformv->type = DEFORMV_PROJECTION_SHADOW;
} else {
return;
}
else if ( !Q_stricmp (token, "projectionShadow") )
deformv->type = DEFORMV_PROJECTION_SHADOW;
else
return;
shader->numdeforms++;
}
@ -759,7 +784,7 @@ static void Shader_SkyParms(shader_t *shader, shaderpass_t *pass, char **ptr)
boxname = Shader_ParseString(ptr);
Shader_ParseSkySides(shader->name, boxname, skydome->farbox_textures);
skyheight = Shader_ParseFloat(ptr);
skyheight = Shader_ParseFloat(shader, ptr);
if (!skyheight)
{
skyheight = 512.0f;
@ -782,7 +807,7 @@ static void Shader_FogParms ( shader_t *shader, shaderpass_t *pass, char **ptr )
// else
div = 1.0f;
Shader_ParseVector ( ptr, color );
Shader_ParseVector (shader, ptr, color );
VectorScale ( color, div, color );
ColorNormalize ( color, fcolor );
@ -790,7 +815,7 @@ static void Shader_FogParms ( shader_t *shader, shaderpass_t *pass, char **ptr )
shader->fog_color[1] = FloatToByte ( fcolor[1] );
shader->fog_color[2] = FloatToByte ( fcolor[2] );
shader->fog_color[3] = 255;
shader->fog_dist = Shader_ParseFloat ( ptr );
shader->fog_dist = Shader_ParseFloat (shader, ptr );
if ( shader->fog_dist <= 0.0f ) {
shader->fog_dist = 128.0f;
@ -1519,14 +1544,14 @@ void Shader_WriteOutGenerics_f(void)
if (sbuiltins[i].qrtype == QR_OPENGL)
{
if (sbuiltins[i].apiver == 100)
name = va("gles/%s.glsl", sbuiltins[i].name);
name = va("gles/eg_%s.glsl", sbuiltins[i].name);
else
name = va("glsl/%s.glsl", sbuiltins[i].name);
name = va("glsl/eg_%s.glsl", sbuiltins[i].name);
}
else if (sbuiltins[i].qrtype == QR_DIRECT3D9)
name = va("hlsl/%s.hlsl", sbuiltins[i].name);
name = va("hlsl/eg_%s.hlsl", sbuiltins[i].name);
else if (sbuiltins[i].qrtype == QR_DIRECT3D11)
name = va("hlsl11/%s.hlsl", sbuiltins[i].name);
name = va("hlsl11/eg_%s.hlsl", sbuiltins[i].name);
if (name)
{
@ -1609,6 +1634,7 @@ struct shader_field_names_s shader_unif_names[] =
{"l_lightcolourscale", SP_LIGHTCOLOURSCALE},
{"l_projmatrix", SP_LIGHTPROJMATRIX},
{"l_cubematrix", SP_LIGHTCUBEMATRIX},
{"l_shadowmapinfo", SP_LIGHTSHADOWMAPINFO},
{"e_rendertexturescale", SP_RENDERTEXTURESCALE},
{NULL}
@ -2195,6 +2221,12 @@ static qboolean Shaderpass_MapGen (shader_t *shader, shaderpass_t *pass, char *t
pass->texgen = T_GEN_REFRACTION;
pass->tcgen = TC_GEN_BASE; //FIXME: moo!
}
else if (!Q_stricmp (tname, "$refractiondepth"))
{
shader->flags |= SHADER_HASREFRACT;
pass->texgen = T_GEN_REFRACTIONDEPTH;
pass->tcgen = TC_GEN_BASE; //FIXME: moo!
}
else if (!Q_stricmp (tname, "$ripplemap"))
{
shader->flags |= SHADER_HASRIPPLEMAP;
@ -2238,7 +2270,7 @@ static void Shaderpass_AnimMap (shader_t *shader, shaderpass_t *pass, char **ptr
pass->tcgen = TC_GEN_BASE;
pass->flags |= SHADER_PASS_ANIMMAP;
pass->texgen = T_GEN_ANIMMAP;
pass->anim_fps = (int)Shader_ParseFloat (ptr);
pass->anim_fps = (int)Shader_ParseFloat (shader, ptr);
pass->anim_numframes = 0;
for ( ; ; )
@ -2340,7 +2372,7 @@ static void Shaderpass_RGBGen (shader_t *shader, shaderpass_t *pass, char **ptr)
else if (!Q_stricmp (token, "wave"))
{
pass->rgbgen = RGB_GEN_WAVE;
Shader_ParseFunc ( ptr, &pass->rgbgen_func);
Shader_ParseFunc (shader, ptr, &pass->rgbgen_func);
}
else if (!Q_stricmp(token, "entity"))
pass->rgbgen = RGB_GEN_ENTITY;
@ -2359,7 +2391,7 @@ static void Shaderpass_RGBGen (shader_t *shader, shaderpass_t *pass, char **ptr)
pass->rgbgen = RGB_GEN_CONST;
pass->rgbgen_func.type = SHADER_FUNC_CONSTANT;
Shader_ParseVector (ptr, pass->rgbgen_func.args);
Shader_ParseVector (shader, ptr, pass->rgbgen_func.args);
}
else if (!Q_stricmp (token, "topcolor"))
pass->rgbgen = RGB_GEN_TOPCOLOR;
@ -2375,7 +2407,7 @@ static void Shaderpass_AlphaGen (shader_t *shader, shaderpass_t *pass, char **pt
if (!Q_stricmp (token, "portal"))
{
pass->alphagen = ALPHA_GEN_PORTAL;
shader->portaldist = Shader_ParseFloat(ptr);
shader->portaldist = Shader_ParseFloat(shader, ptr);
if (!shader->portaldist)
shader->portaldist = 256;
shader->flags |= SHADER_AGEN_PORTAL;
@ -2392,7 +2424,7 @@ static void Shaderpass_AlphaGen (shader_t *shader, shaderpass_t *pass, char **pt
{
pass->alphagen = ALPHA_GEN_WAVE;
Shader_ParseFunc (ptr, &pass->alphagen_func);
Shader_ParseFunc (shader, ptr, &pass->alphagen_func);
}
else if ( !Q_stricmp (token, "lightingspecular"))
{
@ -2402,7 +2434,7 @@ static void Shaderpass_AlphaGen (shader_t *shader, shaderpass_t *pass, char **pt
{
pass->alphagen = ALPHA_GEN_CONST;
pass->alphagen_func.type = SHADER_FUNC_CONSTANT;
pass->alphagen_func.args[0] = fabs(Shader_ParseFloat(ptr));
pass->alphagen_func.args[0] = fabs(Shader_ParseFloat(shader, ptr));
}
}
static void Shaderpass_AlphaShift (shader_t *shader, shaderpass_t *pass, char **ptr) //for alienarena
@ -2419,9 +2451,9 @@ static void Shaderpass_AlphaShift (shader_t *shader, shaderpass_t *pass, char **
//arg2 = timeshift
//arg3 = timescale
speed = Shader_ParseFloat(ptr);
min = Shader_ParseFloat(ptr);
max = Shader_ParseFloat(ptr);
speed = Shader_ParseFloat(shader, ptr);
min = Shader_ParseFloat(shader, ptr);
max = Shader_ParseFloat(shader, ptr);
pass->alphagen_func.args[0] = min + (max - min)/2;
pass->alphagen_func.args[1] = (max - min)/2;
@ -2597,7 +2629,7 @@ static void Shaderpass_TcMod (shader_t *shader, shaderpass_t *pass, char **ptr)
token = Shader_ParseString (ptr);
if (!Q_stricmp (token, "rotate"))
{
tcmod->args[0] = -Shader_ParseFloat(ptr) / 360.0f;
tcmod->args[0] = -Shader_ParseFloat(shader, ptr) / 360.0f;
if (!tcmod->args[0])
{
return;
@ -2607,21 +2639,21 @@ static void Shaderpass_TcMod (shader_t *shader, shaderpass_t *pass, char **ptr)
}
else if ( !Q_stricmp (token, "scale") )
{
tcmod->args[0] = Shader_ParseFloat (ptr);
tcmod->args[1] = Shader_ParseFloat (ptr);
tcmod->args[0] = Shader_ParseFloat (shader, ptr);
tcmod->args[1] = Shader_ParseFloat (shader, ptr);
tcmod->type = SHADER_TCMOD_SCALE;
}
else if ( !Q_stricmp (token, "scroll") )
{
tcmod->args[0] = Shader_ParseFloat (ptr);
tcmod->args[1] = Shader_ParseFloat (ptr);
tcmod->args[0] = Shader_ParseFloat (shader, ptr);
tcmod->args[1] = Shader_ParseFloat (shader, ptr);
tcmod->type = SHADER_TCMOD_SCROLL;
}
else if (!Q_stricmp(token, "stretch"))
{
shaderfunc_t func;
Shader_ParseFunc(ptr, &func);
Shader_ParseFunc(shader, ptr, &func);
tcmod->args[0] = func.type;
for (i = 1; i < 5; ++i)
@ -2631,13 +2663,13 @@ static void Shaderpass_TcMod (shader_t *shader, shaderpass_t *pass, char **ptr)
else if (!Q_stricmp (token, "transform"))
{
for (i = 0; i < 6; ++i)
tcmod->args[i] = Shader_ParseFloat (ptr);
tcmod->args[i] = Shader_ParseFloat (shader, ptr);
tcmod->type = SHADER_TCMOD_TRANSFORM;
}
else if (!Q_stricmp (token, "turb"))
{
for (i = 0; i < 4; i++)
tcmod->args[i] = Shader_ParseFloat (ptr);
tcmod->args[i] = Shader_ParseFloat (shader, ptr);
tcmod->type = SHADER_TCMOD_TURB;
}
else
@ -2658,10 +2690,10 @@ static void Shaderpass_Scale ( shader_t *shader, shaderpass_t *pass, char **ptr
tcmod->type = SHADER_TCMOD_SCALE;
token = Shader_ParseString ( ptr );
token = Shader_ParseString (ptr);
if (!strcmp(token, "static"))
{
tcmod->args[0] = Shader_ParseFloat ( ptr );
tcmod->args[0] = Shader_ParseFloat (shader, ptr);
}
else
{
@ -2673,10 +2705,10 @@ static void Shaderpass_Scale ( shader_t *shader, shaderpass_t *pass, char **ptr
if (**ptr == ',')
*ptr+=1;
token = Shader_ParseString ( ptr );
token = Shader_ParseString (ptr);
if (!strcmp(token, "static"))
{
tcmod->args[1] = Shader_ParseFloat ( ptr );
tcmod->args[1] = Shader_ParseFloat (shader, ptr);
}
else
{
@ -2686,7 +2718,7 @@ static void Shaderpass_Scale ( shader_t *shader, shaderpass_t *pass, char **ptr
pass->numtcmods++;
}
static void Shaderpass_Scroll ( shader_t *shader, shaderpass_t *pass, char **ptr )
static void Shaderpass_Scroll (shader_t *shader, shaderpass_t *pass, char **ptr)
{
//seperate x and y
char *token;
@ -2698,7 +2730,7 @@ static void Shaderpass_Scroll ( shader_t *shader, shaderpass_t *pass, char **ptr
if (!strcmp(token, "static"))
{
tcmod->type = SHADER_TCMOD_SCROLL;
tcmod->args[0] = Shader_ParseFloat ( ptr );
tcmod->args[0] = Shader_ParseFloat (shader, ptr );
}
else
{
@ -2710,7 +2742,7 @@ static void Shaderpass_Scroll ( shader_t *shader, shaderpass_t *pass, char **ptr
if (!strcmp(token, "static"))
{
tcmod->type = SHADER_TCMOD_SCROLL;
tcmod->args[1] = Shader_ParseFloat ( ptr );
tcmod->args[1] = Shader_ParseFloat (shader, ptr );
}
else
{
@ -2767,22 +2799,22 @@ static void Shaderpass_NoLightMap ( shader_t *shader, shaderpass_t *pass, char *
static void Shaderpass_Red(shader_t *shader, shaderpass_t *pass, char **ptr)
{
pass->rgbgen = RGB_GEN_CONST;
pass->rgbgen_func.args[0] = Shader_ParseFloat(ptr);
pass->rgbgen_func.args[0] = Shader_ParseFloat(shader, ptr);
}
static void Shaderpass_Green(shader_t *shader, shaderpass_t *pass, char **ptr)
{
pass->rgbgen = RGB_GEN_CONST;
pass->rgbgen_func.args[1] = Shader_ParseFloat(ptr);
pass->rgbgen_func.args[1] = Shader_ParseFloat(shader, ptr);
}
static void Shaderpass_Blue(shader_t *shader, shaderpass_t *pass, char **ptr)
{
pass->rgbgen = RGB_GEN_CONST;
pass->rgbgen_func.args[2] = Shader_ParseFloat(ptr);
pass->rgbgen_func.args[2] = Shader_ParseFloat(shader, ptr);
}
static void Shaderpass_Alpha(shader_t *shader, shaderpass_t *pass, char **ptr)
{
pass->alphagen = ALPHA_GEN_CONST;
pass->alphagen_func.args[0] = Shader_ParseFloat(ptr);
pass->alphagen_func.args[0] = Shader_ParseFloat(shader, ptr);
}
static void Shaderpass_MaskColor(shader_t *shader, shaderpass_t *pass, char **ptr)
{
@ -2806,7 +2838,7 @@ static void Shaderpass_MaskAlpha(shader_t *shader, shaderpass_t *pass, char **pt
}
static void Shaderpass_AlphaTest(shader_t *shader, shaderpass_t *pass, char **ptr)
{
if (Shader_ParseFloat(ptr) == 0.5)
if (Shader_ParseFloat(shader, ptr) == 0.5)
pass->shaderbits |= SBITS_ATEST_GE128;
else
Con_Printf("unsupported alphatest value\n");
@ -4171,6 +4203,7 @@ void Shader_DefaultSkybox(char *shortname, shader_t *s, const void *args)
char *Shader_DefaultBSPWater(char *shortname)
{
int wstyle;
if (r_wateralpha.value == 0)
wstyle = -1;
else if (r_fastturb.ival)
@ -4184,118 +4217,137 @@ char *Shader_DefaultBSPWater(char *shortname)
else
wstyle = 1;
{
#ifdef GLQUAKE
if (wstyle > 2 && !gl_config.ext_framebuffer_objects)
wstyle = 2;
if (wstyle > 2 && !gl_config.ext_framebuffer_objects)
wstyle = 2;
#endif
switch(wstyle)
{
case -1: //invisible
return (
switch(wstyle)
{
case -1: //invisible
return (
"{\n"
"surfaceparm nodraw\n"
"surfaceparm nodlight\n"
"}\n"
);
case 0: //fastturb
return (
"{\n"
"{\n"
"surfaceparm nodraw\n"
"surfaceparm nodlight\n"
"map $whiteimage\n"
"rgbgen const $r_fastturbcolour\n"
"}\n"
);
case 0: //fastturb
return (
"surfaceparm nodlight\n"
"}\n"
);
default:
case 1: //vanilla style
return (
"{\n"
"program defaultwarp\n"
"{\n"
"{\n"
"map $whiteimage\n"
"rgbgen const $r_fastturbcolour\n"
"}\n"
"surfaceparm nodlight\n"
"}\n"
);
default:
case 1: //vanilla style
return (
"{\n"
"program defaultwarp\n"
"{\n"
"map $diffuse\n"
"tcmod turb 0.02 0.1 0.5 0.1\n"
"if r_wateralpha != 1\n"
"map $diffuse\n"
"tcmod turb 0.02 0.1 0.5 0.1\n"
"if !$#ALPHA\n"
"[\n"
"if r_wateralpha < 1\n"
"[\n"
"alphagen const $r_wateralpha\n"
"blendfunc gl_src_alpha gl_one_minus_src_alpha\n"
"]\n"
"}\n"
"surfaceparm nodlight\n"
"][\n"
"if $#ALPHA < 1\n"
"[\n"
"alphagen const $#ALPHA\n"
"blendfunc gl_src_alpha gl_one_minus_src_alpha\n"
"]\n"
"]\n"
"}\n"
);
case 2: //refraction of the underwater surface, with a fresnel
return (
"surfaceparm nodlight\n"
"}\n"
);
case 2: //refraction of the underwater surface, with a fresnel
return (
"{\n"
"surfaceparm nodlight\n"
"{\n"
"surfaceparm nodlight\n"
"{\n"
"map $refraction\n"
"}\n"
"{\n"
"map $normalmap\n"
"}\n"
"{\n"
"map $diffuse\n"
"}\n"
"program altwater#FRESNEL=4\n"
"map $refraction\n"
"}\n"
);
case 3: //reflections
return (
"{\n"
"surfaceparm nodlight\n"
"{\n"
"map $refraction\n"
"}\n"
"{\n"
"map $normalmap\n"
"}\n"
"{\n"
"map $reflection\n"
"}\n"
"program altwater#REFLECT#FRESNEL=4\n"
"map $normalmap\n"
"}\n"
);
case 4: //ripples
return (
"{\n"
"surfaceparm nodlight\n"
"{\n"
"map $refraction\n"
"}\n"
"{\n"
"map $normalmap\n"
"}\n"
"{\n"
"map $diffuse\n"
"}\n"
"{\n"
"map $ripplemap\n"
"}\n"
"program altwater#RIPPLEMAP#FRESNEL=4\n"
"map $diffuse\n"
"}\n"
);
case 5: //ripples+reflections
return (
// "{\n"
// "map $refractiondepth\n"
// "}\n"
"program altwater#FRESNEL=4\n"
"}\n"
);
case 3: //reflections
return (
"{\n"
"surfaceparm nodlight\n"
"{\n"
"surfaceparm nodlight\n"
"{\n"
"map $refraction\n"
"}\n"
"{\n"
"map $normalmap\n"
"}\n"
"{\n"
"map $reflection\n"
"}\n"
"{\n"
"map $ripplemap\n"
"}\n"
"program altwater#REFLECT#RIPPLEMAP#FRESNEL=4\n"
"map $refraction\n"
"}\n"
);
}
"{\n"
"map $normalmap\n"
"}\n"
"{\n"
"map $reflection\n"
"}\n"
// "{\n"
// "map $refractiondepth\n"
// "}\n"
"program altwater#REFLECT#FRESNEL=4\n"
"}\n"
);
case 4: //ripples
return (
"{\n"
"surfaceparm nodlight\n"
"{\n"
"map $refraction\n"
"}\n"
"{\n"
"map $normalmap\n"
"}\n"
"{\n"
"map $diffuse\n"
"}\n"
// "{\n"
// "map $refractiondepth\n"
// "}\n"
"{\n"
"map $ripplemap\n"
"}\n"
"program altwater#RIPPLEMAP#FRESNEL=4\n"
"}\n"
);
case 5: //ripples+reflections
return (
"{\n"
"surfaceparm nodlight\n"
"{\n"
"map $refraction\n"
"}\n"
"{\n"
"map $normalmap\n"
"}\n"
"{\n"
"map $reflection\n"
"}\n"
// "{\n"
// "map $refractiondepth\n"
// "}\n"
"{\n"
"map $ripplemap\n"
"}\n"
"program altwater#REFLECT#RIPPLEMAP#FRESNEL=4\n"
"}\n"
);
}
}
@ -4310,62 +4362,16 @@ void Shader_DefaultBSPQ2(char *shortname, shader_t *s, const void *args)
"}\n"
);
}
else if (!strncmp(shortname, "warp/", 5))
else if (!strncmp(shortname, "warp/", 5) || !strncmp(shortname, "warp33/", 7) || !strncmp(shortname, "warp66/", 7))
{
Shader_DefaultScript(shortname, s, Shader_DefaultBSPWater(shortname));
}
else if (!strncmp(shortname, "warp33/", 7))
{
else if (!strncmp(shortname, "trans/", 6))
Shader_DefaultScript(shortname, s,
"{\n"
"{\n"
"map $diffuse\n"
"tcmod turb 0 0.01 0.5 0\n"
"alphagen const 0.333\n"
"blendfunc blend\n"
"}\n"
"}\n"
);
}
else if (!strncmp(shortname, "warp66/", 7))
{
Shader_DefaultScript(shortname, s,
"{\n"
"{\n"
"map $diffuse\n"
"tcmod turb 0 0.01 0.5 0\n"
"alphagen const 0.666\n"
"blendfunc blend\n"
"}\n"
"}\n"
);
}
else if (!strncmp(shortname, "trans/", 7))
Shader_DefaultScript(shortname, s,
"{\n"
"{\n"
"map $diffuse\n"
"alphagen const 1\n"
"blendfunc blend\n"
"}\n"
"}\n"
);
else if (!strncmp(shortname, "trans33/", 7))
Shader_DefaultScript(shortname, s,
"{\n"
"{\n"
"map $diffuse\n"
"alphagen const 0.333\n"
"blendfunc blend\n"
"}\n"
"}\n"
);
else if (!strncmp(shortname, "trans66/", 7))
Shader_DefaultScript(shortname, s,
"{\n"
"{\n"
"map $diffuse\n"
"alphagen const 0.666\n"
"alphagen const $#ALPHA\n"
"blendfunc blend\n"
"}\n"
"}\n"
@ -4798,8 +4804,15 @@ static int R_LoadShader ( char *name, shader_gen_t *defaultgen, const char *gena
if (!*name)
name = "gfx/white";
*(int*)shortname = 0;
COM_StripExtension ( name, shortname, sizeof(shortname));
if (strchr(name, '#'))
{
Q_strncpyz(shortname, name, sizeof(shortname));
}
else
{
*(int*)shortname = 0;
COM_StripExtension ( name, shortname, sizeof(shortname));
}
COM_CleanUpPath(shortname);

View File

@ -1940,15 +1940,13 @@ void GL_EndRenderBuffer_DepthOnly(texid_t depthtexture, int texsize)
}
}
static void Sh_GenShadowFace(dlight_t *l, shadowmesh_t *smesh, int face, float proj[16])
static void Sh_GenShadowFace(dlight_t *l, shadowmesh_t *smesh, int face, int smsize, float proj[16])
{
qboolean oxv;
vec3_t t1,t2, t3;
texture_t *tex;
int tno;
int smsize = SHADOWMAP_SIZE;
//FIXME: figure out the four lines bounding the light cone by just adding its +forward+/-right+/-up values. if any point towards a plane (and starts outside that plane), and the point of intersection with that line and the frustum side plane is infront of the near clip plane, then that light frustum needs to be rendered...
switch(face)
{
@ -1998,7 +1996,7 @@ static void Sh_GenShadowFace(dlight_t *l, shadowmesh_t *smesh, int face, float p
qglViewport (0, 0, smsize, smsize);
else
{
qglViewport ((face%3 * smsize), ((face>=3)*smsize), smsize, smsize);
qglViewport ((face%3 * SHADOWMAP_SIZE) + (SHADOWMAP_SIZE-smsize)/2, ((face>=3)*SHADOWMAP_SIZE) + (SHADOWMAP_SIZE-smsize)/2, smsize, smsize);
}
//fixme
@ -2082,22 +2080,22 @@ void Sh_GenShadowMap (dlight_t *l, qbyte *lvis)
{
if (isspot)
{
shadowmap[isspot] = GL_AllocNewTexture("***shadowmap***", smsize, smsize, 0);
shadowmap[isspot] = GL_AllocNewTexture("***shadowmap2dspot***", SHADOWMAP_SIZE, SHADOWMAP_SIZE, 0);
GL_MTBind(0, GL_TEXTURE_2D, shadowmap[isspot]);
#ifdef DBG_COLOURNOTDEPTH
qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, smsize, smsize, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
#else
qglTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32_ARB, smsize, smsize, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
qglTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32_ARB, SHADOWMAP_SIZE, SHADOWMAP_SIZE, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
#endif
}
else
{
shadowmap[isspot] = GL_AllocNewTexture("***shadowmap***", smsize*3, smsize*2, 0);
shadowmap[isspot] = GL_AllocNewTexture("***shadowmap2dcube***", SHADOWMAP_SIZE*3, SHADOWMAP_SIZE*2, 0);
GL_MTBind(0, GL_TEXTURE_2D, shadowmap[isspot]);
#ifdef DBG_COLOURNOTDEPTH
qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, smsize*3, smsize*2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
#else
qglTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32_ARB, smsize*3, smsize*2, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
qglTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32_ARB, SHADOWMAP_SIZE*3, SHADOWMAP_SIZE*2, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
#endif
}
@ -2121,7 +2119,7 @@ void Sh_GenShadowMap (dlight_t *l, qbyte *lvis)
/*set framebuffer*/
GL_BeginRenderBuffer_DepthOnly(shadowmap[isspot]);
GLBE_SetupForShadowMap(shadowmap[isspot]);
GLBE_SetupForShadowMap(shadowmap[isspot], isspot?smsize:smsize*3, isspot?smsize:smsize*2, smsize / (float)SHADOWMAP_SIZE);
qglViewport(0, 0, smsize*3, smsize*2);
qglClear (GL_DEPTH_BUFFER_BIT);
@ -2135,17 +2133,19 @@ void Sh_GenShadowMap (dlight_t *l, qbyte *lvis)
if (l->fov)
{
Matrix4x4_CM_Projection_Far(r_refdef.m_projection, l->fov, l->fov, nearplane, l->radius);
qglMatrixMode(GL_PROJECTION);
qglLoadMatrixf(r_refdef.m_projection);
qglMatrixMode(GL_MODELVIEW);
if (!gl_config.nofixedfunc)
{
qglMatrixMode(GL_PROJECTION);
qglLoadMatrixf(r_refdef.m_projection);
qglMatrixMode(GL_MODELVIEW);
}
/*single face*/
Sh_GenShadowFace(l, smesh, 0, r_refdef.m_projection);
Sh_GenShadowFace(l, smesh, 0, smsize, r_refdef.m_projection);
}
else
{
Matrix4x4_CM_Projection_Far(r_refdef.m_projection, 90, 90, nearplane, l->radius);
if (!gl_config.nofixedfunc)
{
qglMatrixMode(GL_PROJECTION);
@ -2156,7 +2156,7 @@ void Sh_GenShadowMap (dlight_t *l, qbyte *lvis)
/*generate faces*/
for (f = 0; f < 6; f++)
{
Sh_GenShadowFace(l, smesh, f, r_refdef.m_projection);
Sh_GenShadowFace(l, smesh, f, smsize, r_refdef.m_projection);
}
}
/*end framebuffer*/
@ -2210,7 +2210,7 @@ static void Sh_DrawShadowMapLight(dlight_t *l, vec3_t colour, qbyte *vvis)
if (vvis)
{
if (l->worldshadowmesh)
if (!l->rebuildcache && l->worldshadowmesh)
{
lvis = l->worldshadowmesh->litleaves;
//fixme: check head node first?
@ -2831,7 +2831,6 @@ static void Sh_DrawShadowlessLight(dlight_t *dl, vec3_t colour, qbyte *vvis)
}
void GLBE_SubmitMeshes (qboolean drawworld, int start, int stop);
void GLBE_RenderToTexture(texid_t sourcecol, texid_t sourcedepth, texid_t destcol, qboolean usedepth);
void Sh_DrawCrepuscularLight(dlight_t *dl, float *colours)
{
@ -2903,19 +2902,19 @@ void Sh_DrawCrepuscularLight(dlight_t *dl, float *colours)
Sh_ScissorOff();
GLBE_RenderToTexture(r_nulltex, r_nulltex, crepuscular_texture_id, false);
GLBE_RenderToTexture(r_nulltex, r_nulltex, crepuscular_texture_id, r_nulltex, false);
BE_SelectMode(BEM_CREPUSCULAR);
BE_SelectDLight(dl, colours);
GLBE_SubmitMeshes(true, SHADER_SORT_PORTAL, SHADER_SORT_BLEND);
GLBE_RenderToTexture(crepuscular_texture_id, r_nulltex, r_nulltex, false);
GLBE_RenderToTexture(crepuscular_texture_id, r_nulltex, r_nulltex, r_nulltex, false);
BE_SelectMode(BEM_STANDARD);
GLBE_DrawMesh_Single(crepuscular_shader, &mesh, NULL, &crepuscular_shader->defaulttextures, 0);
GLBE_RenderToTexture(r_nulltex, r_nulltex, r_nulltex, false);
GLBE_RenderToTexture(r_nulltex, r_nulltex, r_nulltex, r_nulltex, false);
#endif
}

View File

@ -27,6 +27,9 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#ifndef TINT\n"
"#define TINT vec3(0.7, 0.8, 0.7)\n"
"#endif\n"
"#ifndef FOGTINT\n"
"#define FOGTINT vec3(0.2, 0.3, 0.2)\n"
"#endif\n"
"varying vec2 tc;\n"
"varying vec4 tf;\n"
@ -49,17 +52,27 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"uniform sampler2D s_t0; //refract\n"
"uniform sampler2D s_t1; //normalmap\n"
"uniform sampler2D s_t2; //diffuse/reflection\n"
"#ifdef DEPTH\n"
"uniform sampler2D s_t3; //refraction depth\n"
"#ifdef RIPPLEMAP\n"
"uniform sampler2D s_t4; //ripplemap\n"
"#endif\n"
"#else\n"
"#ifdef RIPPLEMAP\n"
"uniform sampler2D s_t3; //ripplemap\n"
"#endif\n"
"#endif\n"
"uniform float e_time;\n"
"void main (void)\n"
"{\n"
"vec2 stc, ntc;\n"
"vec3 n, refr, refl, fres;\n"
"float f;\n"
"vec3 n, refr, refl;\n"
"float fres;\n"
"float depth;\n"
"stc = (1.0 + (tf.xy / tf.w)) * 0.5;\n"
//hack the texture coords slightly so that there are no obvious gaps
"stc.t -= 1.5*norm.z/1080.0;\n"
//apply q1-style warp, just for kicks
"ntc.s = tc.s + sin(tc.t+e_time)*0.125;\n"
@ -71,25 +84,61 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"n -= 1.0 - 4.0/256.0;\n"
"#ifdef RIPPLEMAP\n"
"n += texture2D(s_t3, stc).rgb*3.0;\n"
"n += texture2D(s_t4, stc).rgb*3.0;\n"
"#endif\n"
//the fresnel term decides how transparent the water should be
"f = pow(1.0-abs(dot(normalize(n), normalize(eye))), float(FRESNEL));\n"
"fres = pow(1.0-abs(dot(normalize(n), normalize(eye))), float(FRESNEL));\n"
"#ifdef DEPTH\n"
"float far = #include \"cvar/gl_maxdist\";\n"
"float near = #include \"cvar/gl_mindist\";\n"
//get depth value at the surface
"float sdepth = gl_FragCoord.z;\n"
"sdepth = (2.0*near) / (far + near - sdepth * (far - near));\n"
"sdepth = mix(near, far, sdepth);\n"
//get depth value at the ground beyond the surface.
"float gdepth = texture2D(s_t3, stc).x;\n"
"gdepth = (2.0*near) / (far + near - gdepth * (far - near));\n"
"if (gdepth >= 0.5)\n"
"{\n"
"gdepth = sdepth;\n"
"depth = 0.0;\n"
"}\n"
"else\n"
"{\n"
"gdepth = mix(near, far, gdepth);\n"
"depth = gdepth - sdepth;\n"
"}\n"
//reduce the normals in shallow water (near walls, reduces the pain of linear sampling)
"if (depth < 100)\n"
"n *= depth/100.0;\n"
"#else\n"
"depth = 1;\n"
"#endif \n"
//refraction image (and water fog, if possible)
"refr = texture2D(s_t0, stc + n.st*STRENGTH*cvar_r_glsl_turbscale).rgb * TINT;\n"
"#ifdef DEPTH\n"
"refr = mix(refr, FOGTINT, min(depth/4096, 1));\n"
"#endif\n"
//reflection/diffuse
"#ifdef REFLECT\n"
"refl = texture2D(s_t2, stc - n.st*STRENGTH*cvar_r_glsl_turbscale).rgb;\n"
"#else\n"
"refl = texture2D(s_t2, ntc).xyz;\n"
"#endif\n"
// refl += 0.1*pow(dot(n, vec3(0.0,0.0,1.0)), 64.0);
//FIXME: add specular
"fres = refr * (1.0-f) + refl*f;\n"
//interplate by fresnel
"refr = mix(refr, refl, fres);\n"
// fres = texture2D(s_t2, stc).xyz;
"gl_FragColor = vec4(fres, 1.0);\n"
//done
"gl_FragColor = vec4(refr, 1.0);\n"
"}\n"
"#endif\n"
},
@ -1090,14 +1139,19 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#ifdef FRAGMENT_SHADER\n"
"uniform sampler2D s_t0;\n"
"uniform float e_time;\n"
"#ifndef ALPHA\n"
"uniform float cvar_r_wateralpha;\n"
"#define USEALPHA cvar_r_wateralpha\n"
"#else\n"
"#define USEALPHA float(ALPHA)\n"
"#endif\n"
"void main ()\n"
"{\n"
"vec2 ntc;\n"
"ntc.s = tc.s + sin(tc.t+e_time)*0.125;\n"
"ntc.t = tc.t + sin(tc.s+e_time)*0.125;\n"
"vec3 ts = vec3(texture2D(s_t0, ntc));\n"
"gl_FragColor = fog4(vec4(ts, cvar_r_wateralpha));\n"
"gl_FragColor = fog4(vec4(ts, USEALPHA));\n"
"}\n"
"#endif\n"
},
@ -1584,6 +1638,9 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"uniform float l_lightradius;\n"
"uniform vec3 l_lightcolour;\n"
"uniform vec3 l_lightcolourscale;\n"
"#ifdef PCF\n"
"uniform vec4 l_shadowmapinfo; //xy are the texture scale, z is 1, w is the scale.\n"
"#endif\n"
@ -1593,12 +1650,6 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"float ShadowmapFilter(void)\n"
"{\n"
"#ifdef SPOT\n"
"const vec3 texscale = vec3(1.0/512.0, 1.0/512.0, 1.0);\n"
"#else\n"
"const vec3 texscale = vec3(1.0/(512.0*3.0), 1.0/(512.0*2.0), 1.0);\n"
"#endif\n"
//dehomogonize input
"vec3 shadowcoord = (vtexprojcoord.xyz / vtexprojcoord.w);\n"
@ -1644,6 +1695,9 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"vec4 nsc =l_projmatrix*vec4(t, 1.0);\n"
"shadowcoord = (nsc.xyz / nsc.w);\n"
//scale to match the light's precision and pinch inwards, so we never sample over the edge
"shadowcoord.st *= l_shadowmapinfo.w * (1.0-l_shadowmapinfo.st);\n"
//now bias and relocate it
"shadowcoord = (shadowcoord + axis.xyz) * vec3(0.5/3.0, 0.5/2.0, 0.5);\n"
"#endif\n"
@ -1663,7 +1717,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"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.\n"
"#else\n"
"#define dosamp(x,y) shadow2D(s_t4, shadowcoord.xyz + (vec3(x,y,0.0)*texscale.xyz)).r\n"
"#define dosamp(x,y) shadow2D(s_t4, shadowcoord.xyz + (vec3(x,y,0.0)*l_shadowmapinfo.xyz)).r\n"
"float s = 0.0;\n"
"s += dosamp(-1.0, -1.0);\n"
"s += dosamp(-1.0, 0.0);\n"
@ -1854,18 +1908,10 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"uniform float cvar_r_waterwarp;\n"
"void main ()\n"
"{\n"
"float amptemp;\n"
"vec3 edge;\n"
"edge = texture2D( s_t2, v_edge ).rgb;\n"
"amptemp = (0.010 / 0.625) * cvar_r_waterwarp * edge.x;\n"
"vec3 offset;\n"
"offset = texture2D( s_t1, v_warp ).rgb;\n"
"offset.x = (offset.x - 0.5) * 2.0;\n"
"offset.y = (offset.y - 0.5) * 2.0;\n"
"vec2 temp;\n"
"temp.x = v_stc.x + offset.x * amptemp;\n"
"temp.y = v_stc.y + offset.y * amptemp;\n"
"gl_FragColor = texture2D( s_t0, temp*e_rendertexturescale.st );\n"
"vec2 amp = (0.010 / 0.625) * cvar_r_waterwarp * texture2D(s_t2, v_edge).rg;\n"
"vec3 offset = (texture2D(s_t1, v_warp).rgb - 0.5) * 2.0;\n"
"vec2 temp = v_stc + offset.xy * amp;\n"
"gl_FragColor = texture2D(s_t0, temp*e_rendertexturescale.st);\n"
"}\n"
"#endif\n"
},

View File

@ -229,6 +229,7 @@ typedef struct shaderpass_s {
T_GEN_REFLECTION, //reflection image (mirror-as-fbo)
T_GEN_REFRACTION, //refraction image (portal-as-fbo)
T_GEN_REFRACTIONDEPTH, //refraction image (portal-as-fbo)
T_GEN_RIPPLEMAP, //ripplemap image (water surface distortions-as-fbo)
T_GEN_SOURCECUBE, //used for render-to-texture targets
@ -337,6 +338,7 @@ typedef struct {
SP_LIGHTSCREEN,
SP_LIGHTPROJMATRIX,
SP_LIGHTCUBEMATRIX,
SP_LIGHTSHADOWMAPINFO,
//things that are set immediatly
SP_FIRSTIMMEDIATE, //never set
@ -430,9 +432,10 @@ struct shader_s
SHADER_STATICDATA = 1 << 18, //set if true: no deforms, no tcgen, rgbgen=identitylighting, alphagen=identity, tmu0=st + tmu1=lm(if available) for every pass, no norms
SHADER_HASREFLECT = 1 << 19, //says that we need to generate a reflection image first
SHADER_HASREFRACT = 1 << 20, //says that we need to generate a refraction image first
SHADER_HASNORMALMAP = 1 << 21, //says that we need to load a normalmap texture
SHADER_HASRIPPLEMAP = 1 << 22, //water surface disturbances for water splashes
SHADER_HASGLOSS = 1 << 23, //
SHADER_HASREFRACTDEPTH = 1 << 21, //refraction generation needs to generate a depth texture too.
SHADER_HASNORMALMAP = 1 << 22, //says that we need to load a normalmap texture
SHADER_HASRIPPLEMAP = 1 << 23, //water surface disturbances for water splashes
SHADER_HASGLOSS = 1 << 24, //
} flags;
program_t *prog;
@ -510,6 +513,7 @@ qboolean GLBE_LightCullModel(vec3_t org, model_t *model);
void GLBE_SelectEntity(entity_t *ent);
void GLBE_SelectDLight(dlight_t *dl, vec3_t colour);
void GLBE_SubmitMeshes (qboolean drawworld, int start, int stop);
void GLBE_RenderToTexture(texid_t sourcecol, texid_t sourcedepth, texid_t destcol, texid_t destdepth, qboolean usedepth);
#endif
#ifdef D3D9QUAKE
void D3D9BE_Init(void);
@ -566,7 +570,7 @@ void BE_GenerateProgram(shader_t *shader);
//
void GLBE_PushOffsetShadow(qboolean foobar);
//sets up gl for depth-only FIXME
void GLBE_SetupForShadowMap(texid_t shadowmaptex);
void GLBE_SetupForShadowMap(texid_t shadowmaptex, int texwidth, int texheight, float shadowscale);
//Called from shadowmapping code into backend
void GLBE_BaseEntTextures(void);
void D3D9BE_BaseEntTextures(void);

View File

@ -20,6 +20,9 @@ uniform float cvar_r_glsl_turbscale;
#ifndef TINT
#define TINT vec3(0.7, 0.8, 0.7)
#endif
#ifndef FOGTINT
#define FOGTINT vec3(0.2, 0.3, 0.2)
#endif
varying vec2 tc;
varying vec4 tf;
@ -42,17 +45,27 @@ void main (void)
uniform sampler2D s_t0; //refract
uniform sampler2D s_t1; //normalmap
uniform sampler2D s_t2; //diffuse/reflection
#ifdef DEPTH
uniform sampler2D s_t3; //refraction depth
#ifdef RIPPLEMAP
uniform sampler2D s_t4; //ripplemap
#endif
#else
#ifdef RIPPLEMAP
uniform sampler2D s_t3; //ripplemap
#endif
#endif
uniform float e_time;
void main (void)
{
vec2 stc, ntc;
vec3 n, refr, refl, fres;
float f;
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;
@ -64,24 +77,60 @@ void main (void)
n -= 1.0 - 4.0/256.0;
#ifdef RIPPLEMAP
n += texture2D(s_t3, stc).rgb*3.0;
n += texture2D(s_t4, stc).rgb*3.0;
#endif
//the fresnel term decides how transparent the water should be
f = pow(1.0-abs(dot(normalize(n), normalize(eye))), float(FRESNEL));
fres = pow(1.0-abs(dot(normalize(n), normalize(eye))), float(FRESNEL));
#ifdef DEPTH
float far = #include "cvar/gl_maxdist";
float near = #include "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_t3, 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)
n *= depth/100.0;
#else
depth = 1;
#endif
//refraction image (and water fog, if possible)
refr = texture2D(s_t0, stc + n.st*STRENGTH*cvar_r_glsl_turbscale).rgb * TINT;
#ifdef DEPTH
refr = mix(refr, FOGTINT, min(depth/4096, 1));
#endif
//reflection/diffuse
#ifdef REFLECT
refl = texture2D(s_t2, stc - n.st*STRENGTH*cvar_r_glsl_turbscale).rgb;
#else
refl = texture2D(s_t2, ntc).xyz;
#endif
// refl += 0.1*pow(dot(n, vec3(0.0,0.0,1.0)), 64.0);
//FIXME: add specular
fres = refr * (1.0-f) + refl*f;
//interplate by fresnel
refr = mix(refr, refl, fres);
// fres = texture2D(s_t2, stc).xyz;
gl_FragColor = vec4(fres, 1.0);
//done
gl_FragColor = vec4(refr, 1.0);
}
#endif

View File

@ -17,13 +17,18 @@ void main ()
#ifdef FRAGMENT_SHADER
uniform sampler2D s_t0;
uniform float e_time;
#ifndef ALPHA
uniform float cvar_r_wateralpha;
#define USEALPHA cvar_r_wateralpha
#else
#define USEALPHA float(ALPHA)
#endif
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_t0, ntc));
gl_FragColor = fog4(vec4(ts, cvar_r_wateralpha));
gl_FragColor = fog4(vec4(ts, USEALPHA));
}
#endif

View File

@ -106,6 +106,9 @@ uniform vec3 e_uppercolour;
uniform float l_lightradius;
uniform vec3 l_lightcolour;
uniform vec3 l_lightcolourscale;
#ifdef PCF
uniform vec4 l_shadowmapinfo; //xy are the texture scale, z is 1, w is the scale.
#endif
@ -115,12 +118,6 @@ uniform vec3 l_lightcolourscale;
float ShadowmapFilter(void)
{
#ifdef SPOT
const vec3 texscale = vec3(1.0/512.0, 1.0/512.0, 1.0);
#else
const vec3 texscale = vec3(1.0/(512.0*3.0), 1.0/(512.0*2.0), 1.0);
#endif
//dehomogonize input
vec3 shadowcoord = (vtexprojcoord.xyz / vtexprojcoord.w);
@ -166,6 +163,9 @@ float ShadowmapFilter(void)
vec4 nsc =l_projmatrix*vec4(t, 1.0);
shadowcoord = (nsc.xyz / nsc.w);
//scale to match the light's precision and pinch inwards, so we never sample over the edge
shadowcoord.st *= l_shadowmapinfo.w * (1.0-l_shadowmapinfo.st);
//now bias and relocate it
shadowcoord = (shadowcoord + axis.xyz) * vec3(0.5/3.0, 0.5/2.0, 0.5);
#endif
@ -185,7 +185,7 @@ float ShadowmapFilter(void)
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
#define dosamp(x,y) shadow2D(s_t4, shadowcoord.xyz + (vec3(x,y,0.0)*texscale.xyz)).r
#define dosamp(x,y) shadow2D(s_t4, shadowcoord.xyz + (vec3(x,y,0.0)*l_shadowmapinfo.xyz)).r
float s = 0.0;
s += dosamp(-1.0, -1.0);
s += dosamp(-1.0, 0.0);

View File

@ -29,17 +29,9 @@ uniform vec4 e_rendertexturescale;
uniform float cvar_r_waterwarp;
void main ()
{
float amptemp;
vec3 edge;
edge = texture2D( s_t2, v_edge ).rgb;
amptemp = (0.010 / 0.625) * cvar_r_waterwarp * edge.x;
vec3 offset;
offset = texture2D( s_t1, v_warp ).rgb;
offset.x = (offset.x - 0.5) * 2.0;
offset.y = (offset.y - 0.5) * 2.0;
vec2 temp;
temp.x = v_stc.x + offset.x * amptemp;
temp.y = v_stc.y + offset.y * amptemp;
gl_FragColor = texture2D( s_t0, temp*e_rendertexturescale.st );
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