1
0
Fork 0
forked from fte/fteqw

fix cl_maxfps as a q3 client.

implement cfg_save_auto cvar, to replicated vanilla quake, ish. default off, obviously.
support for Q2RDF_IRGOGGLES (in combination with Q2RF_IR_VISIBLE). untested.
rework vectorvectors to be more predictable. v_right_z is now _much_ more commonly 0.
fix potential sound-related lock-up/console spam.
implement $colored_armor+$colored_powerup macros.
if command now copes with ' quotes.
fix crash on flushing q3bsps.
fix black bits with r_renderscale+cl_sbar 1
implement emulation for legacy q3 shaders when glsl is required. this is primarily for webgl right now, but potentially also useful with any gles2 port (fixme: still need to tweak d3d11 backend to support this too).
include scrollbar glyphs in the fallback font logic. this is primarily for download progress bars, especially with webgl.
don't try applying gamma to screenshots when using glsl.


git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4976 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2015-08-28 03:13:45 +00:00
parent 636def2dff
commit 31ced9384d
30 changed files with 540 additions and 225 deletions

View file

@ -1145,9 +1145,12 @@ float CL_FilterTime (double time, float wantfps, qboolean ignoreserver) //now re
{
float fps, fpscap;
if (cls.timedemo || cls.protocol == CP_QUAKE3)
if (cls.timedemo)
return -1;
if (cls.protocol == CP_QUAKE3)
ignoreserver = true;
/*ignore the server if we're playing demos, sending to the server only as replies, or if its meant to be disabled (netfps depending on where its called from)*/
if (cls.demoplayback != DPB_NONE || (cls.protocol != CP_QUAKEWORLD && cls.protocol != CP_NETQUAKE) || ignoreserver)
{

View file

@ -1356,6 +1356,7 @@ CL_ClearState
*/
void CL_ClearState (void)
{
extern cvar_t cfg_save_auto;
int i, j;
#ifndef CLIENTONLY
#define serverrunning (sv.state != ss_dead)
@ -1501,6 +1502,9 @@ void CL_ClearState (void)
cl.splitclients = 1;
cl.autotrack_hint = -1;
cl.autotrack_killer = -1;
if (cfg_save_auto.ival && Cvar_UnsavedArchive())
Cmd_ExecuteString("cfg_save\n", RESTRICT_LOCAL);
}
/*

View file

@ -1470,8 +1470,22 @@ void CLQ2_AddPacketEntities (q2frame_t *frame)
ent.framestate.g[FS_REG].lerpweight[0] = fwds;
ent.framestate.g[FS_REG].lerpweight[1] = back;
if ((renderfx & Q2RF_IR_VISIBLE) && (r_refdef.flags & Q2RDF_IRGOGGLES))
{
//IR googles make ir visible ents visible in pure red.
ent.shaderRGBAf[0] = 1;
ent.shaderRGBAf[1] = 0;
ent.shaderRGBAf[2] = 0;
//bypasses world lighting
ent.light_known = true;
VectorSet(ent.light_avg, 1, 1, 1);
VectorSet(ent.light_range, 0, 0, 0);
//(yes, its a bit shit. not even a post-process thing)
}
// add to refresh list
V_AddEntity (&ent);
ent.light_known = false;
// color shells generate a seperate entity for the main model

View file

@ -113,45 +113,46 @@ typedef struct
keyname_t keynames[] =
{
{"TAB", K_TAB},
{"ENTER", K_ENTER},
{"ESCAPE", K_ESCAPE},
{"SPACE", K_SPACE},
{"BACKSPACE", K_BACKSPACE},
{"UPARROW", K_UPARROW},
{"DOWNARROW", K_DOWNARROW},
{"LEFTARROW", K_LEFTARROW},
{"RIGHTARROW", K_RIGHTARROW},
{"TAB", K_TAB},
{"ENTER", K_ENTER},
{"RETURN", K_ENTER},
{"ESCAPE", K_ESCAPE},
{"SPACE", K_SPACE},
{"BACKSPACE", K_BACKSPACE},
{"UPARROW", K_UPARROW},
{"DOWNARROW", K_DOWNARROW},
{"LEFTARROW", K_LEFTARROW},
{"RIGHTARROW", K_RIGHTARROW},
{"LALT", K_LALT},
{"RALT", K_RALT},
{"LCTRL", K_LCTRL},
{"RCTRL", K_RCTRL},
{"LSHIFT", K_LSHIFT},
{"RSHIFT", K_RSHIFT},
{"ALT", K_LALT}, //depricated name
{"CTRL", K_CTRL}, //depricated name
{"SHIFT", K_SHIFT}, //depricated name
{"LALT", K_LALT},
{"RALT", K_RALT},
{"LCTRL", K_LCTRL},
{"RCTRL", K_RCTRL},
{"LSHIFT", K_LSHIFT},
{"RSHIFT", K_RSHIFT},
{"ALT", K_ALT}, //depricated name
{"CTRL", K_CTRL}, //depricated name
{"SHIFT", K_SHIFT}, //depricated name
{"F1", K_F1},
{"F2", K_F2},
{"F3", K_F3},
{"F4", K_F4},
{"F5", K_F5},
{"F6", K_F6},
{"F7", K_F7},
{"F8", K_F8},
{"F9", K_F9},
{"F10", K_F10},
{"F11", K_F11},
{"F12", K_F12},
{"F1", K_F1},
{"F2", K_F2},
{"F3", K_F3},
{"F4", K_F4},
{"F5", K_F5},
{"F6", K_F6},
{"F7", K_F7},
{"F8", K_F8},
{"F9", K_F9},
{"F10", K_F10},
{"F11", K_F11},
{"F12", K_F12},
{"INS", K_INS},
{"DEL", K_DEL},
{"PGDN", K_PGDN},
{"PGUP", K_PGUP},
{"HOME", K_HOME},
{"END", K_END},
{"INS", K_INS},
{"DEL", K_DEL},
{"PGDN", K_PGDN},
{"PGUP", K_PGUP},
{"HOME", K_HOME},
{"END", K_END},
{"KP_HOME", K_KP_HOME},
@ -205,61 +206,61 @@ keyname_t keynames[] =
{"VOLUP", K_VOLUP},
{"VOLDOWN", K_VOLDOWN},
{"JOY1", K_JOY1},
{"JOY2", K_JOY2},
{"JOY3", K_JOY3},
{"JOY4", K_JOY4},
{"JOY1", K_JOY1},
{"JOY2", K_JOY2},
{"JOY3", K_JOY3},
{"JOY4", K_JOY4},
{"AUX1", K_AUX1},
{"AUX2", K_AUX2},
{"AUX3", K_AUX3},
{"AUX4", K_AUX4},
{"AUX5", K_AUX5},
{"AUX6", K_AUX6},
{"AUX7", K_AUX7},
{"AUX8", K_AUX8},
{"AUX9", K_AUX9},
{"AUX10", K_AUX10},
{"AUX11", K_AUX11},
{"AUX12", K_AUX12},
{"AUX13", K_AUX13},
{"AUX14", K_AUX14},
{"AUX15", K_AUX15},
{"AUX16", K_AUX16},
{"AUX17", K_AUX17},
{"AUX18", K_AUX18},
{"AUX19", K_AUX19},
{"AUX20", K_AUX20},
{"AUX21", K_AUX21},
{"AUX22", K_AUX22},
{"AUX23", K_AUX23},
{"AUX24", K_AUX24},
{"AUX25", K_AUX25},
{"AUX26", K_AUX26},
{"AUX27", K_AUX27},
{"AUX28", K_AUX28},
{"AUX29", K_AUX29},
{"AUX30", K_AUX30},
{"AUX31", K_AUX31},
{"AUX32", K_AUX32},
{"AUX1", K_AUX1},
{"AUX2", K_AUX2},
{"AUX3", K_AUX3},
{"AUX4", K_AUX4},
{"AUX5", K_AUX5},
{"AUX6", K_AUX6},
{"AUX7", K_AUX7},
{"AUX8", K_AUX8},
{"AUX9", K_AUX9},
{"AUX10", K_AUX10},
{"AUX11", K_AUX11},
{"AUX12", K_AUX12},
{"AUX13", K_AUX13},
{"AUX14", K_AUX14},
{"AUX15", K_AUX15},
{"AUX16", K_AUX16},
{"AUX17", K_AUX17},
{"AUX18", K_AUX18},
{"AUX19", K_AUX19},
{"AUX20", K_AUX20},
{"AUX21", K_AUX21},
{"AUX22", K_AUX22},
{"AUX23", K_AUX23},
{"AUX24", K_AUX24},
{"AUX25", K_AUX25},
{"AUX26", K_AUX26},
{"AUX27", K_AUX27},
{"AUX28", K_AUX28},
{"AUX29", K_AUX29},
{"AUX30", K_AUX30},
{"AUX31", K_AUX31},
{"AUX32", K_AUX32},
{"PAUSE", K_PAUSE},
{"PAUSE", K_PAUSE},
{"MWHEELUP", K_MWHEELUP},
{"MWHEELDOWN", K_MWHEELDOWN},
{"MWHEELUP", K_MWHEELUP},
{"MWHEELDOWN", K_MWHEELDOWN},
{"PRINTSCREEN", K_PRINTSCREEN},
{"CAPSLOCK", K_CAPSLOCK},
{"SCROLLLOCK", K_SCRLCK},
{"PRINTSCREEN", K_PRINTSCREEN},
{"CAPSLOCK", K_CAPSLOCK},
{"SCROLLLOCK", K_SCRLCK},
{"SEMICOLON", ';'}, // because a raw semicolon seperates commands
{"PLUS", '+'}, // because "shift++" is inferior to shift+plus
{"SEMICOLON", ';'}, // because a raw semicolon seperates commands
{"PLUS", '+'}, // because "shift++" is inferior to shift+plus
{"TILDE", '~'},
{"BACKQUOTE", '`'},
{"BACKSLASH", '\\'},
{"TILDE", '~'},
{"BACKQUOTE", '`'},
{"BACKSLASH", '\\'},
{NULL,0}
{NULL, 0}
};
#if defined(CSQC_DAT) || defined(MENU_DAT)

View file

@ -574,7 +574,7 @@ static void SL_PostDraw (menu_t *menu)
y += 8;
}
Draw_FunStringWidth (lx, y, "^h(press k for keybind help)", w, false, false);
Draw_FunStringWidth (lx, y, "^h(left/rightarrow for different info)", w, false, false);
}
}
else

View file

@ -1017,11 +1017,12 @@ void M_Menu_Quit_f (void)
menu_t *quitmenu;
int i;
int mode;
extern cvar_t cfg_save_auto;
char *arg = Cmd_Argv(1);
if (!strcmp(arg, "force"))
mode = 0;
else if (!strcmp(arg, "forcesave"))
else if (!strcmp(arg, "forcesave") || cfg_save_auto.ival)
{
Cmd_ExecuteString("cfg_save", RESTRICT_LOCAL);
mode = 0;

View file

@ -3456,13 +3456,6 @@ void QCBUILTIN PF_cl_ambientsound(pubprogfuncs_t *prinst, struct globalvars_s *p
S_StaticSound (S_PrecacheSound (samp), pos, vol, attenuation);
}
static void QCBUILTIN PF_cs_vectorvectors (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
VectorCopy(G_VECTOR(OFS_PARM0), csqcg.forward);
VectorNormalize(csqcg.forward);
VectorVectors(csqcg.forward, csqcg.right, csqcg.up);
}
static void QCBUILTIN PF_cs_lightstyle (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int stnum = G_FLOAT(OFS_PARM0);
@ -5392,7 +5385,7 @@ static struct {
{"te_lightning3", PF_cl_te_lightning3, 430}, // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
{"te_beam", PF_cl_te_beam, 431}, // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
{"vectorvectors", PF_cs_vectorvectors, 432}, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
{"vectorvectors", PF_vectorvectors, 432}, // #432 void(vector dir) vectorvectors (DP_QC_VECTORVECTORS)
{"te_plasmaburn", PF_cl_te_plasmaburn, 433}, // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
{"getsurfacenumpoints", PF_getsurfacenumpoints, 434}, // #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)

View file

@ -431,6 +431,7 @@ void R_Clutter_Emit(batch_t **batches)
BE_VBO_Data(&vctx, cctx.soups[i].sdir, sizeof(cctx.soups[i].sdir[0])*cctx.soups[i].numverts, &sect->soups[sect->numsoups].vbo.svector);
BE_VBO_Data(&vctx, cctx.soups[i].tdir, sizeof(cctx.soups[i].tdir[0])*cctx.soups[i].numverts, &sect->soups[sect->numsoups].vbo.tvector);
BE_VBO_Finish(&vctx, cctx.soups[i].idx, sizeof(cctx.soups[i].idx[0])*cctx.soups[i].numidx, &sect->soups[sect->numsoups].vbo.indicies);
sect->soups[sect->numsoups].vbo.colours_bytes = false;
sect->soups[sect->numsoups].mesh.numindexes = sect->soups[sect->numsoups].vbo.indexcount = cctx.soups[i].numidx;
sect->soups[sect->numsoups].mesh.numvertexes = sect->soups[sect->numsoups].vbo.vertcount = cctx.soups[i].numverts;

View file

@ -2452,7 +2452,7 @@ void S_StartSound(int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float f
// pick a channel to play on
target_chan = SND_PickChannel(sc, entnum, entchannel);
if (!target_chan)
return;
break;
S_UpdateSoundCard(sc, false, target_chan, entnum, entchannel, sfx, origin, fvol, attenuation, timeofs, pitchadj, flags);
}

View file

@ -1066,6 +1066,65 @@ char *Macro_CombinedHealth(void)
return macro_buf;
}
char *Macro_Coloured_Armour(void)
{
if (cl.playerview[SP].stats[STAT_ITEMS] & IT_ARMOR3)
return "{^s^xe00%%a^r}";
else if (cl.playerview[SP].stats[STAT_ITEMS] & IT_ARMOR2)
return "{^s^xff0%%a^r}";
else if (cl.playerview[SP].stats[STAT_ITEMS] & IT_ARMOR1)
return "{^s^x0b0%%a^r}";
else
return "{0}";
}
char *Macro_Coloured_Powerups(void)
{
char *quad, *pent, *ring;
quad = (cl.playerview[SP].stats[STAT_ITEMS] & IT_QUAD) ?va("^x03f%s", tp_name_quad.string):"";
pent = (cl.playerview[SP].stats[STAT_ITEMS] & IT_INVULNERABILITY) ?va("^xe00%s", tp_name_pent.string):"";
ring = (cl.playerview[SP].stats[STAT_ITEMS] & IT_INVISIBILITY) ?va("^xff0%s", tp_name_ring.string):"";
if (*quad || *pent || *ring)
{
Q_snprintfz (macro_buf, 32, "{^s%s%s%s^r}", quad, pent, ring);
return macro_buf;
}
else
return "";
}
char *Macro_Coloured_Short_Powerups(void)
{
char *quad, *pent, *ring;
quad = (cl.playerview[SP].stats[STAT_ITEMS] & IT_QUAD) ?"^x03fq":"";
pent = (cl.playerview[SP].stats[STAT_ITEMS] & IT_INVULNERABILITY) ?"^xe00p":"";
ring = (cl.playerview[SP].stats[STAT_ITEMS] & IT_INVISIBILITY) ?"^xff0r":"";
if (*quad || *pent || *ring)
{
Q_snprintfz (macro_buf, 32, "{^s%s%s%s^r}", quad, pent, ring);
return macro_buf;
}
else
return "";
}
char *Macro_LastIP(void)
{
return "---";
}
char *Macro_MP3Info(void)
{
return "---";
}
char *Macro_Match_Status(void)
{
return "---";
}
char *Macro_LastTrigger_Match(void)
{
return "---";
}
/*
$matchname
you can use to get the name of the match
@ -1132,19 +1191,19 @@ static void TP_InitMacros(void)
Cmd_AddMacro("droploc", Macro_LastDrop, true);
Cmd_AddMacro("droptime", Macro_LastDropTime, true);
// Cmd_AddMacro("matchstatus", Macro_Match_Status, false);
// Cmd_AddMacro("mp3info", , false);
// Cmd_AddMacro("triggermatch", Macro_LastTrigger_Match, false);
Cmd_AddMacro("matchstatus", Macro_Match_Status, false);
Cmd_AddMacro("mp3info", Macro_MP3Info, false);
Cmd_AddMacro("triggermatch", Macro_LastTrigger_Match, false);
//new, fte only (at least when first implemented)
Cmd_AddMacro("chealth", Macro_CombinedHealth, true);
//added for ezquake compatability
// Cmd_AddMacro("lastip", Macro_LastIP, false);
Cmd_AddMacro("lastip", Macro_LastIP, false);
Cmd_AddMacro("ping", Macro_Latency, false);
// Cmd_AddMacro("colored_armor", Macro_Coloured_Armour, true); //*shudder*
// Cmd_AddMacro("colored_powerups", Macro_Coloured_Powerups, true);
// Cmd_AddMacro("colored_short_powerups", Macro_Coloured_Short_Powerups, true);
Cmd_AddMacro("colored_armor", Macro_Coloured_Armour, true); //*shudder*
Cmd_AddMacro("colored_powerups", Macro_Coloured_Powerups, true);
Cmd_AddMacro("colored_short_powerups", Macro_Coloured_Short_Powerups, true);
Cmd_AddMacro("gamedir", Macro_Gamedir, false);
Cmd_AddMacro("lastloc", Macro_Last_Location, true);
Cmd_AddMacro("lastpowerup", Macro_LastSeenPowerup, true);
@ -2614,7 +2673,10 @@ static void TP_FindModelNumbers (void)
continue;
for (j=0, item=tp_items ; j<NUMITEMS ; j++, item++)
if (!strcmp(s, item->modelname))
{
model2item[i] = item;
break;
}
}
}
@ -2945,7 +3007,7 @@ more:
}
qboolean R_CullSphere (vec3_t org, float radius);
static qboolean TP_IsItemVisible(item_vis_t *visitem)
static qboolean TP_IsItemVisible(item_vis_t *visitem) //BE sure that pmove.skipent is set correctly first
{
vec3_t end, v;
trace_t trace;
@ -2956,8 +3018,6 @@ static qboolean TP_IsItemVisible(item_vis_t *visitem)
if (R_CullSphere(visitem->entorg, visitem->radius))
return false;
pmove.skipent = -1;
VectorNegate (visitem->dir, v);
VectorNormalize (v);
VectorMA (visitem->entorg, visitem->radius, v, end);
@ -3119,6 +3179,7 @@ static void TP_FindPoint (void)
player_info_t *info, *bestinfo = NULL;
item_vis_t visitem;
extern cvar_t v_viewheight;
int oldskip = pmove.skipent;
if (vars.pointtime == realtime)
return;
@ -3126,6 +3187,8 @@ static void TP_FindPoint (void)
if (!cl.validsequence)
goto nothing;
pmove.skipent = cl.playerview[SP].viewentity;
ang[0] = cl.playerview[SP].viewangles[0]; ang[1] = cl.playerview[SP].viewangles[1]; ang[2] = 0;
AngleVectors (ang, visitem.forward, visitem.right, visitem.up);
VectorCopy (cl.playerview[SP].simorg, visitem.vieworg);
@ -3149,12 +3212,9 @@ static void TP_FindPoint (void)
// special check for armors
if (item->itemflag == (it_ra|it_ya|it_ga))
{
switch (ent->skinnum)
{
case 0: if (!(pointflags_dmm & it_ga)) continue;
case 1: if (!(pointflags_dmm & it_ya)) continue;
default: if (!(pointflags_dmm & it_ra)) continue;
}
item += 1 + bound(0, ent->skinnum, 2);
if (!(item->itemflag & pointflags_dmm))
continue;
}
VectorAdd (ent->origin, item->offset, visitem.entorg);
@ -3266,13 +3326,7 @@ static void TP_FindPoint (void)
if (!bestitem->cvar)
{
// armors are special
switch (bestent->skinnum)
{
case 0: p = tp_name_ga.string; break;
case 1: p = tp_name_ya.string; break;
default: p = tp_name_ra.string;
}
p = tp_name_nothing.string;
}
else
{
@ -3291,6 +3345,7 @@ nothing:
vars.pointtype = POINT_TYPE_ITEM;
}
vars.pointtime = realtime;
pmove.skipent = oldskip;
}

View file

@ -48,7 +48,8 @@ typedef struct cmdalias_s
cmdalias_t *cmd_alias;
cvar_t cfg_save_all = CVARFD("cfg_save_all", "", CVAR_ARCHIVE|CVAR_NOTFROMSERVER, "If 1, cfg_save ALWAYS saves all cvars. If 0, cfg_save only ever saves archived cvars. If empty, cfg_saves all cvars only when an explicit filename was given.");
cvar_t cfg_save_all = CVARFD("cfg_save_all", "", CVAR_ARCHIVE|CVAR_NOTFROMSERVER, "If 1, cfg_save ALWAYS saves all cvars. If 0, cfg_save only ever saves archived cvars. If empty, cfg_save saves all cvars only when an explicit filename was given (ie: when not used internally via quit menu options).");
cvar_t cfg_save_auto = CVARFD("cfg_save_auto", "0", CVAR_ARCHIVE|CVAR_NOTFROMSERVER, "If 1, the config will automatically be saved and without prompts. If 0, you'll have to save your config manually (possibly via prompts from the quit menu).");
cvar_t cl_warncmd = CVARF("cl_warncmd", "1", CVAR_NOSAVE|CVAR_NORESET);
cvar_t cl_aliasoverlap = CVARF("cl_aliasoverlap", "1", CVAR_NOTFROMSERVER);
@ -2396,7 +2397,27 @@ const char *If_Token(const char *func, const char **end)
while(*func <= ' ' && *func)
func++;
s = COM_ParseToken(func, IFPUNCT);
if (*func == '\'')
{
char *o = com_token;
func++;
while (*func)
{
if (*func == '\'')
{
func++;
break;
}
if (o < com_token + sizeof(com_token)-1)
*o++ = *func;
func++;
}
*o = 0;
s = func;
}
else
s = COM_ParseToken(func, IFPUNCT);
if (*com_token == '(')
{
@ -3280,6 +3301,7 @@ void Cmd_Init (void)
Cmd_AddCommand ("set", Cmd_set_f);
Cmd_AddCommand ("setfl", Cmd_set_f);
Cmd_AddCommand ("set_calc", Cmd_set_f);
Cmd_AddCommand ("set_tp", Cmd_set_f);
Cmd_AddCommand ("seta", Cmd_set_f);
Cmd_AddCommand ("seta_calc", Cmd_set_f);
Cmd_AddCommand ("vstr", Cmd_Vstr_f);

View file

@ -1768,6 +1768,7 @@ qboolean Alias_GAliasBuildMesh(mesh_t *mesh, vbo_t **vbop, galiasinfo_t *inf, in
meshcache.vbo.svector = inf->vbo_skel_svector;
meshcache.vbo.tvector = inf->vbo_skel_tvector;
meshcache.vbo.colours[0] = inf->vborgba;
meshcache.vbo.colours_bytes = !!inf->ofs_rgbaub;
memset(&meshcache.vbo.bonenums, 0, sizeof(meshcache.vbo.bonenums));
memset(&meshcache.vbo.boneweights, 0, sizeof(meshcache.vbo.boneweights));
meshcache.vbo.numbones = 0;
@ -1835,6 +1836,7 @@ qboolean Alias_GAliasBuildMesh(mesh_t *mesh, vbo_t **vbop, galiasinfo_t *inf, in
meshcache.vbo.svector = inf->vbo_skel_svector;
meshcache.vbo.tvector = inf->vbo_skel_tvector;
meshcache.vbo.colours[0] = inf->vborgba;
meshcache.vbo.colours_bytes = !!inf->ofs_rgbaub;
meshcache.vbo.bonenums = inf->vbo_skel_bonenum;
meshcache.vbo.boneweights = inf->vbo_skel_bweight;
meshcache.vbo.numbones = inf->numbones;

View file

@ -4274,6 +4274,7 @@ static cmodel_t *CM_LoadMap (model_t *mod, qbyte *filein, size_t filelen, qboole
Q_snprintfz (name, sizeof(name), "*%i:%s", i, wmod->name);
mod = Mod_FindName (name);
*mod = *wmod;
mod->entities = NULL;
mod->submodelof = wmod;
Q_strncpyz(mod->name, name, sizeof(mod->name));
memset(&mod->memgroup, 0, sizeof(mod->memgroup));

View file

@ -269,25 +269,18 @@ if (sides == 0)
void VVPerpendicularVector(vec3_t dst, const vec3_t src)
{
if (!src[0])
if (!src[0] && !src[1])
{
dst[0] = 1;
dst[1] = dst[2] = 0;
}
else if (!src[1])
{
dst[1] = 1;
if (src[2])
dst[1] = -1;
else
dst[1] = 0;
dst[0] = dst[2] = 0;
}
else if (!src[2])
{
dst[2] = 1;
dst[0] = dst[1] = 0;
}
else
{
dst[0] = -src[1];
dst[1] = src[0];
dst[0] = src[1];
dst[1] = -src[0];
dst[2] = 0;
VectorNormalize(dst);
}

View file

@ -4480,6 +4480,17 @@ void QCBUILTIN PF_anglemod (pubprogfuncs_t *prinst, struct globalvars_s *pr_glob
G_FLOAT(OFS_RETURN) = v;
}
//void(vector dir) vectorvectors
//Writes new values for v_forward, v_up, and v_right based on the given forward vector
void QCBUILTIN PF_vectorvectors (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
world_t *world = prinst->parms->user;
VectorCopy(G_VECTOR(OFS_PARM0), world->g.v_forward);
VectorNormalize(world->g.v_forward);
VectorVectors(world->g.v_forward, world->g.v_right, world->g.v_up);
}
//Maths functions
////////////////////////////////////////////////////
/*

View file

@ -103,6 +103,7 @@ void QCBUILTIN PF_rint (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
void QCBUILTIN PF_floor (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_ceil (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_anglemod (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_vectorvectors (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_Tokenize (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_tokenizebyseparator (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_tokenize_console (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);

View file

@ -1216,6 +1216,7 @@ typedef struct q1usercmd_s
#define RDF_WATERWARP (1u<<18)
#define RDF_CUSTOMPOSTPROC (1u<<19)
#define RDF_ANTIALIAS (1u<<20) //fxaa, or possibly even just fsaa
#define RDF_RENDERSCALE (1u<<21)
#define RDF_ALLPOSTPROC (RDF_BLOOM|RDF_FISHEYE|RDF_WATERWARP|RDF_CUSTOMPOSTPROC|RDF_ANTIALIAS) //these flags require rendering to an fbo for the various different post-processing shaders.

View file

@ -663,7 +663,7 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../libs/speex,..\client,../libs/freetype2/include,../common,../server,../gl,../sw,../qclib,../libs,../libs/dxsdk7/include"
PreprocessorDefinitions="_DEBUG;GLQUAKE;WIN32;_WINDOWS;MULTITHREAD;BOTLIB_STATIC;USE_MSVCRT_DEBUG"
PreprocessorDefinitions="_DEBUG;GLQUAKE;WIN32;_WINDOWS;MULTITHREAD;BOTLIB_STATIC;USE_MSVCRT_DEBUG;GLSLONLY"
BasicRuntimeChecks="3"
SmallerTypeCheck="true"
RuntimeLibrary="1"

View file

@ -94,6 +94,8 @@ struct {
union programhandle_u allblackshader;
int allblack_mvp;
program_t *programfixedemu[8];
qboolean initeddepthnorm;
const shader_t *depthnormshader;
texid_t tex_normals;
@ -128,7 +130,6 @@ struct {
batch_t dummybatch;
vbo_t dummyvbo;
int colourarraytype;
int currentvbo;
int currentebo;
int currentvao;
@ -139,6 +140,7 @@ struct {
float modelmatrixinv[16];
float modelviewmatrix[16];
int colourarraytype;
vec4_t pendingcolourflat;
int pendingcolourvbo;
void *pendingcolourpointer;
@ -531,6 +533,7 @@ static void BE_ApplyAttributes(unsigned int bitstochange, unsigned int bitstoend
{
unsigned int i;
#ifndef GLSLONLY
//legacy colour attribute (including flat shaded)
if ((bitstochange) & (1u<<VATTR_LEG_COLOUR))
{
@ -628,6 +631,7 @@ static void BE_ApplyAttributes(unsigned int bitstochange, unsigned int bitstoend
qglDisableClientState(GL_VERTEX_ARRAY);
}
}
#endif
if (!((bitstochange|bitstoendisable) & ((1u<<VATTR_LEG_FIRST)-1)))
return;
@ -656,14 +660,14 @@ static void BE_ApplyAttributes(unsigned int bitstochange, unsigned int bitstoend
}
break;
case VATTR_COLOUR:
if (!shaderstate.sourcevbo->colours[0].gl.addr)
if (!shaderstate.pendingcolourvbo && !shaderstate.pendingcolourpointer)
{
shaderstate.sha_attr &= ~(1u<<i);
qglDisableVertexAttribArray(i);
continue;
}
GL_SelectVBO(shaderstate.sourcevbo->colours[0].gl.vbo);
qglVertexAttribPointer(VATTR_COLOUR, 4, shaderstate.colourarraytype, ((shaderstate.colourarraytype==GL_FLOAT)?GL_FALSE:GL_TRUE), 0, shaderstate.sourcevbo->colours[0].gl.addr);
GL_SelectVBO(shaderstate.pendingcolourvbo);
qglVertexAttribPointer(VATTR_COLOUR, 4, shaderstate.colourarraytype, ((shaderstate.colourarraytype==GL_FLOAT)?GL_FALSE:GL_TRUE), 0, shaderstate.pendingcolourpointer);
break;
#if MAXRLIGHTMAPS > 1
case VATTR_COLOUR2:
@ -847,7 +851,7 @@ void GLBE_SetupVAO(vbo_t *vbo, unsigned int vaodynamic, unsigned int vaostatic)
shaderstate.sourcevbo = vbo;
shaderstate.pendingvertexvbo = shaderstate.sourcevbo->coord.gl.vbo;
shaderstate.pendingvertexpointer = shaderstate.sourcevbo->coord.gl.addr;
shaderstate.colourarraytype = GL_FLOAT;
shaderstate.colourarraytype = shaderstate.sourcevbo->colours_bytes?GL_UNSIGNED_BYTE:GL_FLOAT;
shaderstate.pendingtexcoordvbo[0] = shaderstate.sourcevbo->texcoord.gl.vbo;
shaderstate.pendingtexcoordpointer[0] = shaderstate.sourcevbo->texcoord.gl.addr;
shaderstate.pendingtexcoordparts[0] = 2;
@ -1424,7 +1428,7 @@ void GLBE_Init(void)
memset(&shaderstate, 0, sizeof(shaderstate));
shaderstate.curentity = &r_worldentity;
be_maxpasses = gl_mtexarbable;
be_maxpasses = gl_config_nofixedfunc?1:gl_mtexarbable;
gl_stencilbits = 0;
if (gl_config.glversion >= 3.0 && gl_config_nofixedfunc)
{
@ -1526,9 +1530,13 @@ void GLBE_Init(void)
#define MAX_ARRAY_VERTS 65535
static vecV_t vertexarray[MAX_ARRAY_VERTS];
#ifndef GLSLONLY
#if 1//ndef GLSLONLY
static avec4_t coloursarray[MAX_ARRAY_VERTS];
#ifdef FTE_TARGET_WEB
static float texcoordarray[1][MAX_ARRAY_VERTS*2];
#else
static float texcoordarray[SHADER_PASS_MAX][MAX_ARRAY_VERTS*2];
#endif
/*========================================== texture coord generation =====================================*/
@ -2302,7 +2310,7 @@ static void GenerateVertexDeforms(const shader_t *shader)
shaderstate.pendingvertexvbo = 0;
}
#ifndef GLSLONLY
#if 1//ndef GLSLONLY
/*======================================alpha ===============================*/
@ -2419,10 +2427,11 @@ static void GenerateColourMods(const shaderpass_t *pass)
mesh_t *meshlist;
meshlist = shaderstate.meshes[0];
if (pass->flags & SHADER_PASS_NOCOLORARRAY && qglColor4fv)
if (pass->flags & SHADER_PASS_NOCOLORARRAY)
{
colourgen(pass, 1, meshlist->colors4f_array[0], &shaderstate.pendingcolourflat, meshlist);
alphagen(pass, 1, meshlist->colors4f_array[0], &shaderstate.pendingcolourflat, meshlist);
shaderstate.colourarraytype = 0;
shaderstate.pendingcolourvbo = 0;
shaderstate.pendingcolourpointer = NULL;
}
@ -2435,6 +2444,7 @@ static void GenerateColourMods(const shaderpass_t *pass)
{
shaderstate.pendingcolourflat[0] = shaderstate.pendingcolourflat[1] = shaderstate.pendingcolourflat[2] = 0;
alphagen(pass, 1, meshlist->colors4f_array[0], &shaderstate.pendingcolourflat, meshlist);
shaderstate.colourarraytype = 0;
shaderstate.pendingcolourvbo = 0;
shaderstate.pendingcolourpointer = NULL;
return;
@ -2443,6 +2453,7 @@ static void GenerateColourMods(const shaderpass_t *pass)
{
shaderstate.pendingcolourflat[0] = shaderstate.pendingcolourflat[1] = shaderstate.pendingcolourflat[2] = 1;
alphagen(pass, 1, meshlist->colors4f_array[0], &shaderstate.pendingcolourflat, meshlist);
shaderstate.colourarraytype = 0;
shaderstate.pendingcolourvbo = 0;
shaderstate.pendingcolourpointer = NULL;
return;
@ -2451,6 +2462,7 @@ static void GenerateColourMods(const shaderpass_t *pass)
{
VectorCopy(shaderstate.curentity->light_avg, shaderstate.pendingcolourflat);
shaderstate.pendingcolourflat[3] = shaderstate.curentity->shaderRGBAf[3];
shaderstate.colourarraytype = 0;
shaderstate.pendingcolourvbo = 0;
shaderstate.pendingcolourpointer = NULL;
return;
@ -2460,6 +2472,7 @@ static void GenerateColourMods(const shaderpass_t *pass)
//if its vetex lighting, just use the vbo
if (((pass->rgbgen == RGB_GEN_VERTEX_LIGHTING && shaderstate.identitylighting == 1) || pass->rgbgen == RGB_GEN_VERTEX_EXACT) && pass->alphagen == ALPHA_GEN_VERTEX)
{
shaderstate.colourarraytype = shaderstate.sourcevbo->colours_bytes?GL_UNSIGNED_BYTE:GL_FLOAT;
shaderstate.pendingcolourvbo = shaderstate.sourcevbo->colours[0].gl.vbo;
shaderstate.pendingcolourpointer = shaderstate.sourcevbo->colours[0].gl.addr;
return;
@ -3214,6 +3227,12 @@ static void BE_Program_Set_Attributes(const program_t *prog, unsigned int perm,
case SP_E_COLOURS:
qglUniform4fvARB(ph, 1, (GLfloat*)shaderstate.curentity->shaderRGBAf);
break;
case SP_S_COLOUR:
if (shaderstate.colourarraytype)
qglUniform4fARB(ph, 1, 1, 1, 1); //invalid use
else
qglUniform4fvARB(ph, 1, (GLfloat*)shaderstate.pendingcolourflat);
break;
case SP_E_COLOURSIDENT:
if (shaderstate.flags & BEF_FORCECOLOURMOD)
qglUniform4fvARB(ph, 1, (GLfloat*)shaderstate.curentity->shaderRGBAf);
@ -3383,9 +3402,8 @@ static void BE_Program_Set_Attributes(const program_t *prog, unsigned int perm,
}
}
static void BE_RenderMeshProgram(const shader_t *shader, const shaderpass_t *pass)
static void BE_RenderMeshProgram(const shader_t *shader, const shaderpass_t *pass, program_t *p)
{
program_t *p = shader->prog;
int i;
int perm;
@ -3449,17 +3467,6 @@ static void BE_RenderMeshProgram(const shader_t *shader, const shaderpass_t *pas
else
#endif
{
#ifndef GLSLONLY
if (0)//pass->numtcmods)
GenerateTCMods(pass, 0);
else
#endif
{
shaderstate.pendingtexcoordparts[0] = 2;
shaderstate.pendingtexcoordvbo[0] = shaderstate.sourcevbo->texcoord.gl.vbo;
shaderstate.pendingtexcoordpointer[0] = shaderstate.sourcevbo->texcoord.gl.addr;
}
for (i = 0; i < pass->numMergedPasses; i++)
{
Shader_BindTextureForPass(i, pass+i);
@ -4001,7 +4008,15 @@ static void DrawMeshes(void)
if (!altshader)
altshader = shaderstate.shader_light[shaderstate.lightmode];
if (altshader && altshader->prog)
BE_RenderMeshProgram(altshader, altshader->passes);
{
shaderstate.pendingcolourvbo = shaderstate.sourcevbo->colours[0].gl.vbo;
shaderstate.pendingcolourpointer = shaderstate.sourcevbo->colours[0].gl.addr;
shaderstate.colourarraytype = shaderstate.sourcevbo->colours_bytes?GL_UNSIGNED_BYTE:GL_FLOAT;
shaderstate.pendingtexcoordparts[0] = 2;
shaderstate.pendingtexcoordvbo[0] = shaderstate.sourcevbo->texcoord.gl.vbo;
shaderstate.pendingtexcoordpointer[0] = shaderstate.sourcevbo->texcoord.gl.addr;
BE_RenderMeshProgram(altshader, altshader->passes, altshader->prog);
}
#ifndef GLSLONLY
else
BE_LegacyLighting();
@ -4012,7 +4027,15 @@ static void DrawMeshes(void)
if (!altshader)
altshader = shaderstate.depthnormshader;
if (altshader && altshader->prog)
BE_RenderMeshProgram(altshader, altshader->passes);
{
shaderstate.pendingcolourvbo = shaderstate.sourcevbo->colours[0].gl.vbo;
shaderstate.pendingcolourpointer = shaderstate.sourcevbo->colours[0].gl.addr;
shaderstate.colourarraytype = shaderstate.sourcevbo->colours_bytes?GL_UNSIGNED_BYTE:GL_FLOAT;
shaderstate.pendingtexcoordparts[0] = 2;
shaderstate.pendingtexcoordvbo[0] = shaderstate.sourcevbo->texcoord.gl.vbo;
shaderstate.pendingtexcoordpointer[0] = shaderstate.sourcevbo->texcoord.gl.addr;
BE_RenderMeshProgram(altshader, altshader->passes, altshader->prog);
}
break;
#endif
case BEM_CREPUSCULAR:
@ -4023,7 +4046,15 @@ static void DrawMeshes(void)
altshader = shaderstate.crepopaqueshader;
if (altshader && altshader->prog)
BE_RenderMeshProgram(altshader, altshader->passes);
{
shaderstate.pendingcolourvbo = shaderstate.sourcevbo->colours[0].gl.vbo;
shaderstate.pendingcolourpointer = shaderstate.sourcevbo->colours[0].gl.addr;
shaderstate.colourarraytype = shaderstate.sourcevbo->colours_bytes?GL_UNSIGNED_BYTE:GL_FLOAT;
shaderstate.pendingtexcoordparts[0] = 2;
shaderstate.pendingtexcoordvbo[0] = shaderstate.sourcevbo->texcoord.gl.vbo;
shaderstate.pendingtexcoordpointer[0] = shaderstate.sourcevbo->texcoord.gl.addr;
BE_RenderMeshProgram(altshader, altshader->passes, altshader->prog);
}
break;
case BEM_DEPTHONLY:
altshader = shaderstate.curshader->bemoverrides[bemoverride_depthonly];
@ -4031,7 +4062,15 @@ static void DrawMeshes(void)
altshader = shaderstate.depthonlyshader;
if (altshader && altshader->prog)
BE_RenderMeshProgram(altshader, altshader->passes);
{
shaderstate.pendingcolourvbo = shaderstate.sourcevbo->colours[0].gl.vbo;
shaderstate.pendingcolourpointer = shaderstate.sourcevbo->colours[0].gl.addr;
shaderstate.colourarraytype = shaderstate.sourcevbo->colours_bytes?GL_UNSIGNED_BYTE:GL_FLOAT;
shaderstate.pendingtexcoordparts[0] = 2;
shaderstate.pendingtexcoordvbo[0] = shaderstate.sourcevbo->texcoord.gl.vbo;
shaderstate.pendingtexcoordpointer[0] = shaderstate.sourcevbo->texcoord.gl.addr;
BE_RenderMeshProgram(altshader, altshader->passes, altshader->prog);
}
else
{
GL_DeSelectProgram();
@ -4132,13 +4171,89 @@ static void DrawMeshes(void)
default:
if (shaderstate.curshader->prog)
{
BE_RenderMeshProgram(shaderstate.curshader, shaderstate.curshader->passes);
shaderstate.pendingcolourvbo = shaderstate.sourcevbo->colours[0].gl.vbo;
shaderstate.pendingcolourpointer = shaderstate.sourcevbo->colours[0].gl.addr;
shaderstate.colourarraytype = shaderstate.sourcevbo->colours_bytes?GL_UNSIGNED_BYTE:GL_FLOAT;
shaderstate.pendingtexcoordparts[0] = 2;
shaderstate.pendingtexcoordvbo[0] = shaderstate.sourcevbo->texcoord.gl.vbo;
shaderstate.pendingtexcoordpointer[0] = shaderstate.sourcevbo->texcoord.gl.addr;
BE_RenderMeshProgram(shaderstate.curshader, shaderstate.curshader->passes, shaderstate.curshader->prog);
}
#ifdef GLSLONLY
break;
#else
else if (gl_config_nofixedfunc)
{
#ifdef FTE_TARGET_WEB
int maxverts = 0, m;
mesh_t *meshlist;
for (m = 0; m < shaderstate.meshcount; m++)
{
meshlist = shaderstate.meshes[m];
if (maxverts < meshlist->vbofirstvert + meshlist->numvertexes)
maxverts = meshlist->vbofirstvert + meshlist->numvertexes;
}
#endif
while (passno < shaderstate.curshader->numpasses)
{
int emumode;
p = &shaderstate.curshader->passes[passno];
passno += p->numMergedPasses;
emumode = 0;
emumode = (p->shaderbits & SBITS_ATEST_BITS) >> SBITS_ATEST_SHIFT;
GenerateColourMods(p);
if (!shaderstate.colourarraytype)
{
emumode |= 4;
shaderstate.lastuniform = 0; //FIXME: s_colour uniform might be wrong.
}
#ifdef FTE_TARGET_WEB
else if (!shaderstate.pendingcolourvbo && shaderstate.pendingcolourpointer)
{
shaderstate.streamid = (shaderstate.streamid + 1) & (sizeof(shaderstate.streamvbo)/sizeof(shaderstate.streamvbo[0]) - 1);
GL_SelectVBO(shaderstate.pendingcolourvbo = shaderstate.streamvbo[shaderstate.streamid]);
switch(shaderstate.colourarraytype)
{
case GL_FLOAT:
qglBufferDataARB(GL_ARRAY_BUFFER_ARB, maxverts * sizeof(vec4_t), shaderstate.pendingcolourpointer, GL_STREAM_DRAW_ARB);
break;
case GL_UNSIGNED_BYTE:
qglBufferDataARB(GL_ARRAY_BUFFER_ARB, maxverts * sizeof(byte_vec4_t), shaderstate.pendingcolourpointer, GL_STREAM_DRAW_ARB);
break;
}
shaderstate.pendingcolourpointer = NULL;
}
#endif
BE_GeneratePassTC(p, 0);
#ifdef FTE_TARGET_WEB
if (!shaderstate.pendingtexcoordvbo[0] && shaderstate.pendingtexcoordpointer[0])
{
shaderstate.streamid = (shaderstate.streamid + 1) & (sizeof(shaderstate.streamvbo)/sizeof(shaderstate.streamvbo[0]) - 1);
GL_SelectVBO(shaderstate.pendingtexcoordvbo[0] = shaderstate.streamvbo[shaderstate.streamid]);
qglBufferDataARB(GL_ARRAY_BUFFER_ARB, maxverts * sizeof(float) * shaderstate.pendingtexcoordparts[0], shaderstate.pendingtexcoordpointer[0], GL_STREAM_DRAW_ARB);
shaderstate.pendingtexcoordpointer[0] = NULL;
}
#endif
if (!shaderstate.programfixedemu[emumode])
{
char *modes[] = {
"","#ALPHATEST=>0.0","#ALPHATEST=<0.5","#ALPHATEST=>=0.5",
"#UC","#ALPHATEST=>0.0#UC","#ALPHATEST=<0.5#UC","#ALPHATEST=>=0.5#UC"
};
shaderstate.programfixedemu[emumode] = Shader_FindGeneric(va("fixedemu%s", modes[emumode]), QR_OPENGL);
if (!shaderstate.programfixedemu[emumode])
break;
}
BE_RenderMeshProgram(shaderstate.curshader, p, shaderstate.programfixedemu[emumode]);
}
break;
}
#ifndef GLSLONLY
else
{
GL_DeSelectProgram();
@ -4247,7 +4362,7 @@ static qboolean BE_GenTempMeshVBO(vbo_t **vbo, mesh_t *m)
shaderstate.dummyvbo.colours[0].gl.addr = (void*)len;
shaderstate.dummyvbo.colours[0].gl.vbo = shaderstate.streamvbo[shaderstate.streamid];
len += sizeof(*m->colors4f_array[0]) * m->numvertexes;
shaderstate.colourarraytype = GL_FLOAT;
shaderstate.dummyvbo.colours_bytes = false;
}
else if (m->colors4b_array)
{
@ -4255,13 +4370,13 @@ static qboolean BE_GenTempMeshVBO(vbo_t **vbo, mesh_t *m)
shaderstate.dummyvbo.colours[0].gl.addr = (void*)len;
shaderstate.dummyvbo.colours[0].gl.vbo = shaderstate.streamvbo[shaderstate.streamid];
len += sizeof(*m->colors4b_array) * m->numvertexes;
shaderstate.colourarraytype = GL_UNSIGNED_BYTE;
shaderstate.dummyvbo.colours_bytes = true;
}
else
{
shaderstate.dummyvbo.colours[0].gl.addr = NULL;
shaderstate.dummyvbo.colours[0].gl.vbo = 0;
shaderstate.colourarraytype = GL_FLOAT;
shaderstate.dummyvbo.colours_bytes = false;
}
if (m->normals_array)
@ -4327,12 +4442,12 @@ static qboolean BE_GenTempMeshVBO(vbo_t **vbo, mesh_t *m)
shaderstate.dummyvbo.tvector.gl.addr = m->tnormals_array;
if (m->colors4f_array[0])
{
shaderstate.colourarraytype = GL_FLOAT;
shaderstate.dummyvbo.colours_bytes = false;
shaderstate.dummyvbo.colours[0].gl.addr = m->colors4f_array[0];
}
else
{
shaderstate.colourarraytype = GL_UNSIGNED_BYTE;
shaderstate.dummyvbo.colours_bytes = true;
shaderstate.dummyvbo.colours[0].gl.addr = m->colors4b_array;
}
shaderstate.dummyvbo.bonenums.gl.addr = m->bonenums;
@ -4381,7 +4496,6 @@ void GLBE_DrawMesh_List(shader_t *shader, int nummeshes, mesh_t **meshlist, vbo_
else
{
shaderstate.sourcevbo = vbo;
shaderstate.colourarraytype = GL_FLOAT;
shaderstate.flags = beflags;
if (shaderstate.curentity != &r_worldentity)
GLBE_SelectEntity(&r_worldentity);
@ -4411,7 +4525,6 @@ void GLBE_SubmitBatch(batch_t *batch)
if (batch->vbo)
{
shaderstate.sourcevbo = batch->vbo;
shaderstate.colourarraytype = GL_FLOAT;
if (!batch->vbo->vao)
batch->vbo->vao = shaderstate.streamvao[0];

View file

@ -1078,6 +1078,26 @@ qbyte default_conchar[/*11356*/] =
#include "lhfont.h"
};
static void Font_CopyGlyph(int src, int dst, void *data)
{
int glyphsize = 16;
int y;
int x;
char *srcptr = (char*)data + (src&15)*glyphsize*4 + (src>>4)*glyphsize*256*4;
char *dstptr = (char*)data + (dst&15)*glyphsize*4 + (dst>>4)*glyphsize*256*4;
for (y = 0; y < glyphsize; y++)
{
for (x = 0; x < glyphsize; x++)
{
dstptr[x*4+0] = srcptr[x*4+0];
dstptr[x*4+1] = srcptr[x*4+1];
dstptr[x*4+2] = srcptr[x*4+2];
dstptr[x*4+3] = srcptr[x*4+3];
}
dstptr += 256*4;
srcptr += 256*4;
}
}
static texid_t Font_LoadFallbackConchars(void)
{
texid_t tex;
@ -1096,6 +1116,13 @@ static texid_t Font_LoadFallbackConchars(void)
lump[i*4+1] = 255;
lump[i*4+2] = 255;
}
if (width == 256 && height == 256)
{ //make up some scroll-bar/download-progress-bar chars, so that webgl doesn't look so buggy with the initial pak file(s).
Font_CopyGlyph('[', 128, lump);
Font_CopyGlyph('-', 129, lump);
Font_CopyGlyph(']', 130, lump);
Font_CopyGlyph('o', 131, lump);
}
tex = R_LoadTexture32("charset", width, height, (void*)lump, IF_UIPIC|IF_NOMIPMAP|IF_NOGAMMA);
BZ_Free(lump);
return tex;

View file

@ -268,6 +268,7 @@ typedef struct vbo_s
vboarray_t svector;
vboarray_t tvector;
qboolean colours_bytes;
vboarray_t colours[MAXRLIGHTMAPS];
vboarray_t bonenums;

View file

@ -410,7 +410,7 @@ void R_SetupGL (float stereooffset)
//
// set up viewpoint
//
if (r_refdef.flags & (RDF_ALLPOSTPROC))
if (r_refdef.flags & (RDF_ALLPOSTPROC|RDF_RENDERSCALE))
{
//with fbo postprocessing, we disable all viewport.
r_refdef.pxrect.x = 0;
@ -1156,11 +1156,9 @@ void GLR_DrawPortal(batch_t *batch, batch_t **blist, batch_t *depthmasklist[2],
{
qglMatrixMode(GL_PROJECTION);
qglLoadMatrixf(r_refdef.m_projection);
//portals to mask are relative to the old view still.
qglMatrixMode(GL_MODELVIEW);
qglLoadMatrixf(r_refdef.m_view);
}
//portals to mask are relative to the old view still.
GLBE_SelectEntity(&r_worldentity);
currententity = NULL;
if (gl_config.arb_depth_clamp)
qglEnable(GL_DEPTH_CLAMP_ARB); //ignore the near clip plane(ish), this means nearer portals can still mask further ones.
@ -1198,8 +1196,8 @@ void GLR_DrawPortal(batch_t *batch, batch_t **blist, batch_t *depthmasklist[2],
r_refdef.flipcull &= ~SHADER_CULL_FLIP;
if (r_refdef.m_projection[5]<0)
r_refdef.flipcull ^= SHADER_CULL_FLIP;
GL_CullFace(0);//make sure flipcull takes effect
r_framecount++;
//FIXME: just call Surf_DrawWorld instead?
R_RenderScene();
// if (qglClipPlane)
@ -1229,10 +1227,8 @@ void GLR_DrawPortal(batch_t *batch, batch_t **blist, batch_t *depthmasklist[2],
/*put GL back the way it was*/
qglMatrixMode(GL_PROJECTION);
qglLoadMatrixf(r_refdef.m_projection);
qglMatrixMode(GL_MODELVIEW);
qglLoadMatrixf(r_refdef.m_view);
}
GLBE_SelectEntity(&r_worldentity);
GL_CullFace(0);//make sure flipcull reversion takes effect
@ -1815,11 +1811,13 @@ void GLR_RenderView (void)
}
else if ((r_refdef.flags & (RDF_ALLPOSTPROC)) || renderscale != 1)
{
r_refdef.flags |= RDF_RENDERSCALE;
//the game needs to be drawn to a texture for post processing
if (1)//vid.framebuffer)
{
vid.fbpwidth = (r_refdef.vrect.width * r_refdef.pxrect.width) / vid.width;
vid.fbpheight = (r_refdef.vrect.height * r_refdef.pxrect.width) / vid.height;
vid.fbpheight = (r_refdef.vrect.height * r_refdef.pxrect.height) / vid.height;
}
else
{

View file

@ -248,6 +248,7 @@ char *GLVID_GetRGBInfo(int *truewidth, int *trueheight, enum uploadfmt *fmt)
extern qboolean gammaworks;
int i, c;
qbyte *ret;
extern qboolean r2d_canhwgamma;
*truewidth = vid.fbpwidth;
*trueheight = vid.fbpheight;
@ -310,15 +311,29 @@ char *GLVID_GetRGBInfo(int *truewidth, int *trueheight, enum uploadfmt *fmt)
qglReadPixels (0, 0, (*truewidth), (*trueheight), GL_RGB, GL_UNSIGNED_BYTE, ret);
}
if (gammaworks)
if (gammaworks && r2d_canhwgamma)
{
c = (*truewidth)*(*trueheight)*3;
for (i=0 ; i<c ; i+=3)
if (*fmt == TF_BGRA32 || *fmt == TF_RGBA32)
{
extern qbyte gammatable[256];
ret[i+0] = gammatable[ret[i+0]];
ret[i+1] = gammatable[ret[i+1]];
ret[i+2] = gammatable[ret[i+2]];
c = (*truewidth)*(*trueheight)*4;
for (i=0 ; i<c ; i+=4)
{
extern qbyte gammatable[256];
ret[i+0] = gammatable[ret[i+0]];
ret[i+1] = gammatable[ret[i+1]];
ret[i+2] = gammatable[ret[i+2]];
}
}
else
{
c = (*truewidth)*(*trueheight)*3;
for (i=0 ; i<c ; i+=3)
{
extern qbyte gammatable[256];
ret[i+0] = gammatable[ret[i+0]];
ret[i+1] = gammatable[ret[i+1]];
ret[i+2] = gammatable[ret[i+2]];
}
}
}

View file

@ -1596,7 +1596,7 @@ static void Shader_LoadGeneric(sgeneric_t *g, int qrtype)
}
}
}
static program_t *Shader_FindGeneric(char *name, int qrtype)
program_t *Shader_FindGeneric(char *name, int qrtype)
{
sgeneric_t *g;
@ -1747,6 +1747,8 @@ struct shader_field_names_s shader_unif_names[] =
{"e_light_mul", SP_E_L_MUL},
{"e_light_ambient", SP_E_L_AMBIENT},
{"s_colour", SP_S_COLOUR},
/*rtlight properties, use with caution*/
{"l_lightscreen", SP_LIGHTSCREEN},
{"l_lightradius", SP_LIGHTRADIUS},
@ -3808,6 +3810,15 @@ void Shader_Programify (shader_t *s)
vertexlighting = pass;
else if (pass->texgen == T_GEN_LIGHTMAP && pass->tcgen == TC_GEN_LIGHTMAP)
lightmap = pass;
/*if (pass->numtcmods || (pass->shaderbits & SBITS_ATEST_BITS))
return;
if (pass->texgen == T_GEN_LIGHTMAP && pass->tcgen == TC_GEN_LIGHTMAP)
;
else if (pass->texgen != T_GEN_LIGHTMAP && pass->tcgen == TC_GEN_BASE)
;
else*/
return;
}
if (modellighting)

View file

@ -1120,6 +1120,9 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name))
qglGetDebugMessageLogARB = NULL;
}
#endif
if (!gl_config.gles && gl_config_nofixedfunc)
qglDisableClientState(GL_VERTEX_ARRAY);
}
static const char *glsl_hdrs[] =

View file

@ -2017,34 +2017,34 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#ifdef FRAGMENT_SHADER\n"
"#include \"sys/fog.h\"\n"
"uniform sampler2D s_t0; //diffuse\n"
"uniform sampler2D s_diffuse; //diffuse\n"
"#if defined(BUMP) || defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK)\n"
"uniform sampler2D s_t1; //normalmap\n"
"uniform sampler2D s_normalmap; //normalmap\n"
"#endif\n"
"#ifdef SPECULAR\n"
"uniform sampler2D s_t2; //specular\n"
"uniform sampler2D s_specular; //specular\n"
"#endif\n"
"#ifdef CUBE\n"
"uniform samplerCube s_t3; //projected cubemap\n"
"uniform samplerCube s_projectionmap; //projected cubemap\n"
"#endif\n"
"#ifdef PCF\n"
"#ifdef CUBESHADOW\n"
"uniform samplerCubeShadow s_t4; //shadowmap\n"
"uniform samplerCubeShadow s_shadowmap; //shadowmap\n"
"#else\n"
"#if 0//def GL_ARB_texture_gather\n"
"uniform sampler2D s_t4;\n"
"uniform sampler2D s_shadowmap;\n"
"#else\n"
"uniform sampler2DShadow s_t4;\n"
"uniform sampler2DShadow s_shadowmap;\n"
"#endif\n"
"#endif\n"
"#endif\n"
"#ifdef LOWER\n"
"uniform sampler2D s_t5; //pants colours\n"
"uniform sampler2D s_lower; //pants colours\n"
"uniform vec3 e_lowercolour;\n"
"#endif\n"
"#ifdef UPPER\n"
"uniform sampler2D s_t6; //shirt colours\n"
"uniform sampler2D s_upper; //shirt colours\n"
"uniform vec3 e_uppercolour;\n"
"#endif\n"
@ -2068,7 +2068,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"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);\n"
//#elif defined(CUBESHADOW)
// vec3 shadowcoord = vshadowcoord.xyz / vshadowcoord.w;
// #define dosamp(x,y) shadowCube(s_t4, shadowcoord + vec2(x,y)*texscale.xy).r
// #define dosamp(x,y) shadowCube(s_shadowmap, shadowcoord + vec2(x,y)*texscale.xy).r
"#else\n"
//figure out which axis to use
//texture is arranged thusly:
@ -2113,7 +2113,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#if 0//def GL_ARB_texture_gather\n"
"vec2 ipart, fpart;\n"
"#define dosamp(x,y) textureGatherOffset(s_t4, ipart.xy, vec2(x,y)))\n"
"#define dosamp(x,y) textureGatherOffset(s_shadowmap, ipart.xy, vec2(x,y)))\n"
"vec4 tl = step(shadowcoord.z, dosamp(-1.0, -1.0));\n"
"vec4 bl = step(shadowcoord.z, dosamp(-1.0, 1.0));\n"
"vec4 tr = step(shadowcoord.z, dosamp(1.0, -1.0));\n"
@ -2128,10 +2128,10 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#else\n"
"#ifdef USE_ARB_SHADOW\n"
//with arb_shadow, we can benefit from hardware acclerated pcf, for smoother shadows
"#define dosamp(x,y) shadow2D(s_t4, shadowcoord.xyz + (vec3(x,y,0.0)*l_shadowmapscale.xyx)).r\n"
"#define dosamp(x,y) shadow2D(s_shadowmap, shadowcoord.xyz + (vec3(x,y,0.0)*l_shadowmapscale.xyx)).r\n"
"#else\n"
//this will probably be a bit blocky.
"#define dosamp(x,y) float(texture2D(s_t4, shadowcoord.xy + (vec2(x,y)*l_shadowmapscale.xy)).r >= shadowcoord.z)\n"
"#define dosamp(x,y) float(texture2D(s_shadowmap, shadowcoord.xy + (vec2(x,y)*l_shadowmapscale.xy)).r >= shadowcoord.z)\n"
"#endif\n"
"float s = 0.0;\n"
"#if r_glsl_pcf >= 1 && r_glsl_pcf < 5\n"
@ -2169,25 +2169,29 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"{\n"
//read raw texture samples (offsetmapping munges the tex coords first)
"#ifdef OFFSETMAPPING\n"
"vec2 tcoffsetmap = offsetmap(s_t1, tcbase, eyevector);\n"
"vec2 tcoffsetmap = offsetmap(s_normalmap, tcbase, eyevector);\n"
"#define tcbase tcoffsetmap\n"
"#endif\n"
"vec3 bases = vec3(texture2D(s_t0, tcbase));\n"
"#if defined(FLAT)\n"
"vec3 bases = vec3(1.0);\n"
"#else\n"
"vec3 bases = vec3(texture2D(s_diffuse, tcbase));\n"
"#endif\n"
"#ifdef UPPER\n"
"vec4 uc = texture2D(s_t6, tcbase);\n"
"vec4 uc = texture2D(s_upper, tcbase);\n"
"bases.rgb += uc.rgb*e_uppercolour*uc.a;\n"
"#endif\n"
"#ifdef LOWER\n"
"vec4 lc = texture2D(s_t5, tcbase);\n"
"vec4 lc = texture2D(s_lower, tcbase);\n"
"bases.rgb += lc.rgb*e_lowercolour*lc.a;\n"
"#endif\n"
"#if defined(BUMP) || defined(SPECULAR) || defined(REFLECTCUBEMASK)\n"
"vec3 bumps = normalize(vec3(texture2D(s_t1, tcbase)) - 0.5);\n"
"vec3 bumps = normalize(vec3(texture2D(s_normalmap, tcbase)) - 0.5);\n"
"#elif defined(REFLECTCUBEMASK)\n"
"vec3 bumps = vec3(0.0,0.0,1.0);\n"
"#endif\n"
"#ifdef SPECULAR\n"
"vec4 specs = texture2D(s_t2, tcbase);\n"
"vec4 specs = texture2D(s_specular, tcbase);\n"
"#endif\n"
"float colorscale = max(1.0 - (dot(lightvector, lightvector)/(l_lightradius*l_lightradius)), 0.0);\n"
@ -2221,7 +2225,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#ifdef CUBE\n"
/*filter the colour by the cubemap projection*/
"diff *= textureCube(s_t3, vtexprojcoord.xyz).rgb;\n"
"diff *= textureCube(s_projectionmap, vtexprojcoord.xyz).rgb;\n"
"#endif\n"
"#if defined(SPOT)\n"
@ -2239,7 +2243,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#if defined(PROJECTION)\n"
/*2d projection, not used*/
// diff *= texture2d(s_t3, shadowcoord);
// diff *= texture2d(s_projectionmap, shadowcoord);
"#endif\n"
"gl_FragColor.rgb = fog3additive(diff*colorscale*l_lightcolour);\n"
@ -2914,3 +2918,48 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#endif\n"
},
#endif
#ifdef GLQUAKE
{QR_OPENGL, 110, "fixedemu",
//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.
"#ifdef VERTEX_SHADER\n"
"attribute vec2 v_texcoord;\n"
"varying vec2 tc;\n"
"#ifndef UC\n"
"attribute vec4 v_colour;\n"
"varying vec4 vc;\n"
"#endif\n"
"void main ()\n"
"{\n"
"tc = v_texcoord;\n"
"#ifndef UC\n"
"vc = v_colour;\n"
"#endif\n"
"gl_Position = ftetransform();\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform sampler2D s_t0;\n"
"varying vec2 tc;\n"
"#ifndef UC\n"
"varying vec4 vc;\n"
"#else\n"
"uniform vec4 s_colour;\n"
"#define vc s_colour\n"
"#endif\n"
"float e_time;\n"
"void main ()\n"
"{\n"
"vec4 fc = texture2D(s_t0, tc) * vc;\n"
"#ifdef ALPHATEST\n"
"if (!(fc.a ALPHATEST))\n"
"discard;\n"
"#endif\n"
"gl_FragColor = fc;\n"
"}\n"
"#endif\n"
},
#endif

View file

@ -153,6 +153,7 @@ enum
SBITS_ATEST_LT128 = 0x00002000,
SBITS_ATEST_GE128 = 0x00003000,
#define SBITS_ATEST_BITS 0x0000f000
#define SBITS_ATEST_SHIFT 12
SBITS_MISC_DEPTHWRITE = 0x00010000,
SBITS_MISC_NODEPTHTEST = 0x00020000,
@ -401,6 +402,8 @@ typedef struct {
SP_RENDERTEXTURESCALE, /*multiplier for currentrender->texcoord*/
SP_SOURCESIZE, /*size of $sourcecolour*/
SP_S_COLOUR,
SP_LIGHTRADIUS, /*these light values are realtime lighting*/
SP_LIGHTCOLOUR,
SP_LIGHTCOLOURSCALE,
@ -630,6 +633,8 @@ void Shader_WriteOutGenerics_f(void);
void Shader_RemapShader_f(void);
void Shader_ShowShader_f(void);
program_t *Shader_FindGeneric(char *name, int qrtype);
mfog_t *Mod_FogForOrigin(model_t *wmodel, vec3_t org);
#define BEF_FORCEDEPTHWRITE 1

View file

@ -6500,17 +6500,6 @@ static void QCBUILTIN PF_sv_findchainflags (pubprogfuncs_t *prinst, struct globa
RETURN_EDICT(prinst, chain);
}
//EXTENSION: DP_QC_VECTORVECTORS
//void(vector dir) vectorvectors = #432
//Writes new values for v_forward, v_up, and v_right based on the given forward vector
static void QCBUILTIN PF_vectorvectors (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
VectorCopy(G_VECTOR(OFS_PARM0), P_VEC(v_forward));
VectorNormalize(P_VEC(v_forward));
VectorVectors(P_VEC(v_forward), P_VEC(v_right), P_VEC(v_up));
}
//EXTENSION: KRIMZON_SV_PARSECLIENTCOMMAND
//void(entity e, string s) clientcommand = #440

View file

@ -34,6 +34,7 @@ char shaders[][64] =
"underwaterwarp",
"menutint",
"terrain",
"fixedemu",
""
};

View file

@ -108,7 +108,7 @@ static unsigned int domkeytoshift(unsigned int code)
static int DOM_KeyEvent(int devid, int down, int scan, int uni)
{
extern int shift_down;
// Con_Printf("Key %i %i:%c\n", scan, uni, (char)uni);
// Con_Printf("Key %s %i %i:%c\n", down?"down":"up", scan, uni, uni?(char)uni:' ');
if (shift_down)
{
uni = domkeytoshift(scan);