Added two new projection modes. use r_projection to select alternative projections.
make sure demos freeze at the start, instead of reading everything out of the file while we're still loading content. added a couple of lame 'list' commands. added 'in' command. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4928 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
667e8dec10
commit
a85f3c5c71
22 changed files with 463 additions and 73 deletions
|
@ -244,6 +244,8 @@ void Cam_Unlock(playerview_t *pv)
|
|||
pv->cam_state = CAM_FREECAM;
|
||||
pv->viewentity = (cls.demoplayback)?0:(pv->playernum+1); //free floating
|
||||
Sbar_Changed();
|
||||
|
||||
Skin_FlushPlayers();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -326,12 +326,21 @@ void CL_MakeActive(char *gamename)
|
|||
}
|
||||
cl.matchgametimestart = 0;
|
||||
cls.state = ca_active;
|
||||
|
||||
//this might be expensive, don't count any of this as time spent *playing* the demo. this avoids skipping the first $LOADDURATION seconds.
|
||||
cl.stillloading = true;
|
||||
|
||||
//kill sounds left over from the last map.
|
||||
S_Purge(true);
|
||||
CL_UpdateWindowTitle();
|
||||
|
||||
//kill models left over from the last map.
|
||||
Mod_Purge(MP_MAPCHANGED);
|
||||
|
||||
//and reload shaders now if needed (this was blocked earlier)
|
||||
Shader_DoReload();
|
||||
|
||||
SCR_EndLoadingPlaque();
|
||||
|
||||
Mod_Purge(MP_MAPCHANGED);
|
||||
CL_UpdateWindowTitle();
|
||||
|
||||
TP_ExecTrigger("f_begin", true);
|
||||
if (cls.demoplayback)
|
||||
|
@ -1832,9 +1841,6 @@ void CL_CheckServerInfo(void)
|
|||
if (cl.spectator || cls.demoplayback || atoi(Info_ValueForKey(cl.serverinfo, "allow_lmgamma")))
|
||||
cls.allow_lightmapgamma=true;
|
||||
|
||||
s = Info_ValueForKey(cl.serverinfo, "allow_fish");
|
||||
if (cl.spectator || cls.demoplayback || !*s || atoi(s))
|
||||
cls.allow_postproc=true;
|
||||
s = Info_ValueForKey(cl.serverinfo, "allow_postproc");
|
||||
if (cl.spectator || cls.demoplayback || !*s || atoi(s))
|
||||
cls.allow_postproc=true;
|
||||
|
@ -1893,9 +1899,13 @@ void CL_CheckServerInfo(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
cl.maxpitch = 89.9;
|
||||
cl.minpitch = -89.9;
|
||||
cl.maxpitch = 90;
|
||||
cl.minpitch = -90;
|
||||
}
|
||||
//bound it, such that we never end up looking slightly more back than forwards
|
||||
//FIXME: we should probably tweak our movement code instead.
|
||||
cl.maxpitch = bound(-89.9, cl.maxpitch, 89.9);
|
||||
cl.minpitch = bound(-89.9, cl.minpitch, 89.9);
|
||||
|
||||
cl.hexen2pickups = atoi(Info_ValueForKey(cl.serverinfo, "sv_pupglow"));
|
||||
|
||||
|
@ -4599,6 +4609,7 @@ double Host_Frame (double time)
|
|||
qboolean maxfpsignoreserver;
|
||||
qboolean idle;
|
||||
extern qboolean r_blockvidrestart;
|
||||
static qboolean hadwork;
|
||||
|
||||
RSpeedLocals();
|
||||
|
||||
|
@ -4634,8 +4645,6 @@ double Host_Frame (double time)
|
|||
if (startuppending)
|
||||
CL_StartCinematicOrMenu();
|
||||
|
||||
COM_MainThreadWork();
|
||||
|
||||
#ifdef PLUGINS
|
||||
Plug_Tick();
|
||||
#endif
|
||||
|
@ -4739,7 +4748,16 @@ double Host_Frame (double time)
|
|||
host_frametime = (realtime - oldrealtime)*cl.gamespeed;
|
||||
oldrealtime = realtime;
|
||||
|
||||
if (cls.demoplayback && !cl.stillloading)
|
||||
{
|
||||
extern qboolean shader_reload_needed; //this can take some time when you have weird glsl.
|
||||
qboolean haswork = cl.sendprespawn || COM_HasWork();
|
||||
if (!hadwork && !haswork)
|
||||
CL_ProgressDemoTime();
|
||||
hadwork = haswork;
|
||||
}
|
||||
cl.stillloading = cl.sendprespawn || (cls.state < ca_active && COM_HasWork());
|
||||
COM_MainThreadWork();
|
||||
|
||||
|
||||
#if defined(Q2CLIENT)
|
||||
|
|
|
@ -4801,7 +4801,7 @@ void CL_SetStatInt (int pnum, int stat, int value)
|
|||
cl.players[cls_lastto].statsf[stat]=value;
|
||||
|
||||
for (pnum = 0; pnum < cl.splitclients; pnum++)
|
||||
if (cl.playerview[pnum].cam_spec_track == cls_lastto)
|
||||
if (cl.playerview[pnum].cam_spec_track == cls_lastto && cl.playerview[pnum].cam_state != CAM_FREECAM)
|
||||
CL_SetStat_Internal(pnum, stat, value, value);
|
||||
}
|
||||
else
|
||||
|
@ -4823,7 +4823,7 @@ void CL_SetStatFloat (int pnum, int stat, float value)
|
|||
cl.players[cls_lastto].stats[stat]=value;
|
||||
|
||||
for (pnum = 0; pnum < cl.splitclients; pnum++)
|
||||
if (cl.playerview[pnum].cam_spec_track == cls_lastto)
|
||||
if (cl.playerview[pnum].cam_spec_track == cls_lastto && cl.playerview[pnum].cam_state != CAM_FREECAM)
|
||||
{
|
||||
cl.playerview[pnum].statsf[stat] = value;
|
||||
cl.playerview[pnum].stats[stat] = value;
|
||||
|
|
|
@ -898,9 +898,10 @@ void CL_PredictMovePNum (int seat)
|
|||
|
||||
if (!cl.spectator && (pv->cam_state != CAM_FREECAM || pv->cam_spec_track != -1)) //just in case
|
||||
{
|
||||
if (pv->cam_state != CAM_FREECAM)
|
||||
pv->viewentity = (cls.demoplayback)?0:(pv->playernum+1);
|
||||
pv->cam_state = CAM_FREECAM;
|
||||
pv->cam_spec_track = -1;
|
||||
pv->viewentity = (cls.demoplayback)?0:(pv->playernum+1);
|
||||
}
|
||||
|
||||
#ifdef Q2CLIENT
|
||||
|
|
|
@ -1194,15 +1194,8 @@ void SCR_ShowPic_Remove_f(void)
|
|||
void QDECL SCR_Fov_Callback (struct cvar_s *var, char *oldvalue)
|
||||
{
|
||||
if (var->value < 10)
|
||||
{
|
||||
Cvar_ForceSet(var, "10");
|
||||
return;
|
||||
}
|
||||
if (var->value > 170)
|
||||
{
|
||||
Cvar_ForceSet (var, "170");
|
||||
return;
|
||||
}
|
||||
//highs are capped elsewhere. this allows fisheye to use this cvar automatically.
|
||||
}
|
||||
|
||||
void QDECL SCR_Viewsize_Callback (struct cvar_s *var, char *oldvalue)
|
||||
|
|
|
@ -680,6 +680,8 @@ typedef struct
|
|||
qboolean csqcdebug;
|
||||
qboolean allowsendpacket;
|
||||
|
||||
qboolean stillloading; // set when doing something slow, and the game is still loading.
|
||||
|
||||
char serverinfo[MAX_SERVERINFO_STRING];
|
||||
char serverpaknames[1024];
|
||||
char serverpakcrcs[1024];
|
||||
|
|
|
@ -2932,6 +2932,13 @@ void Media_RecordFrame (void)
|
|||
return;
|
||||
}
|
||||
|
||||
//don't capture frames while we're loading.
|
||||
if (cl.sendprespawn || (cls.state < ca_active && COM_HasWork()))
|
||||
{
|
||||
capturelastvideotime += captureframeinterval;
|
||||
return;
|
||||
}
|
||||
|
||||
//overlay this on the screen, so it appears in the film
|
||||
if (*capturemessage.string)
|
||||
{
|
||||
|
|
|
@ -182,7 +182,7 @@ void M_Options_Remove(menu_t *m)
|
|||
//options menu.
|
||||
void M_Menu_Options_f (void)
|
||||
{
|
||||
extern cvar_t crosshair;
|
||||
extern cvar_t crosshair, r_projection;
|
||||
int y;
|
||||
|
||||
menuoption_t *updatecbo;
|
||||
|
@ -194,13 +194,31 @@ void M_Menu_Options_f (void)
|
|||
NULL
|
||||
};
|
||||
|
||||
static const char *projections[] = {
|
||||
"Regular",
|
||||
"Stereographic",
|
||||
"Fisheye",
|
||||
"Panoramic",
|
||||
"Lambert Azimuthal Equal-Area",
|
||||
NULL
|
||||
};
|
||||
static const char *projectionvalues[] = {
|
||||
"0",
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
NULL
|
||||
};
|
||||
|
||||
menubulk_t bulk[] = {
|
||||
MB_CONSOLECMD("Customize controls", "menu_keys\n", "Modify keyboard and mouse inputs."),
|
||||
MB_CONSOLECMD("Go to console", "toggleconsole\nplay misc/menu2.wav\n", "Open up the engine console."),
|
||||
MB_CONSOLECMD("Reset to defaults", "cvarreset *\nexec default.cfg\nplay misc/menu2.wav\n", "Reloads the default configuration."),
|
||||
MB_CONSOLECMD("Save all settings", "cfg_save\n", "Writes changed settings out to a config file."),
|
||||
MB_SPACING(4),
|
||||
MB_SLIDER("Field of View", scr_fov, 80, 110, 5, NULL),
|
||||
MB_COMBOCVAR("View Projection", r_projection, projections, projectionvalues, NULL),
|
||||
MB_SLIDER("Field of View", scr_fov, 70, 360, 5, NULL),
|
||||
MB_SLIDER("Mouse Speed", sensitivity, 1, 10, 0.2, NULL),
|
||||
MB_SLIDER("Crosshair", crosshair, 0, 22, 1, NULL), // move this to hud setup?
|
||||
MB_CHECKBOXFUNC("Always Run", M_Options_AlwaysRun, 0, "Set movement to run at fastest speed by default."),
|
||||
|
|
|
@ -530,6 +530,45 @@ void R_InitTextures (void)
|
|||
}
|
||||
}
|
||||
|
||||
static int QDECL ShowFileList (const char *name, qofs_t flags, time_t mtime, void *parm, searchpathfuncs_t *spath)
|
||||
{
|
||||
//ignore non-diffuse texture filenames, because they're annoying as heck.
|
||||
if (!strstr(name, "_pants.") && !strstr(name, "_shirt.") && !strstr(name, "_upper.") && !strstr(name, "_lower.") && !strstr(name, "_bump.") && !strstr(name, "_norm.") && !strstr(name, "_gloss.") && !strstr(name, "_luma."))
|
||||
{
|
||||
Con_Printf("%s\n", name);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void R_ListConfigs_f(void)
|
||||
{
|
||||
COM_EnumerateFiles("*.cfg", ShowFileList, NULL);
|
||||
COM_EnumerateFiles("configs/*.cfg", ShowFileList, NULL);
|
||||
}
|
||||
void R_ListFonts_f(void)
|
||||
{
|
||||
COM_EnumerateFiles("charsets/*.*", ShowFileList, NULL);
|
||||
COM_EnumerateFiles("textures/charsets/*.*", ShowFileList, NULL);
|
||||
}
|
||||
void R_ListSkins_f(void)
|
||||
{
|
||||
COM_EnumerateFiles("skins/*.*", ShowFileList, NULL);
|
||||
}
|
||||
void R_ListSkyBoxes_f(void)
|
||||
{
|
||||
//FIXME: this demonstrates why we need a nicer result printer.
|
||||
COM_EnumerateFiles("env/*rt.*", ShowFileList, NULL);
|
||||
COM_EnumerateFiles("env/*px.*", ShowFileList, NULL);
|
||||
COM_EnumerateFiles("env/*posx.*", ShowFileList, NULL);
|
||||
COM_EnumerateFiles("gfx/env/*rt.*", ShowFileList, NULL);
|
||||
COM_EnumerateFiles("gfx/env/*px.*", ShowFileList, NULL);
|
||||
COM_EnumerateFiles("gfx/env/*posx.*", ShowFileList, NULL);
|
||||
COM_EnumerateFiles("textures/env/*rt.*", ShowFileList, NULL);
|
||||
COM_EnumerateFiles("textures/env/*px.*", ShowFileList, NULL);
|
||||
COM_EnumerateFiles("textures/env/*posx.*", ShowFileList, NULL);
|
||||
COM_EnumerateFiles("textures/gfx/env/*rt.*", ShowFileList, NULL);
|
||||
COM_EnumerateFiles("textures/gfx/env/*px.*", ShowFileList, NULL);
|
||||
COM_EnumerateFiles("textures/gfx/env/*posx.*", ShowFileList, NULL);
|
||||
}
|
||||
|
||||
|
||||
void R_SetRenderer_f (void);
|
||||
|
@ -760,6 +799,11 @@ void Renderer_Init(void)
|
|||
// misc
|
||||
Cvar_Register(&con_ocranaleds, "Console controls");
|
||||
|
||||
Cmd_AddCommand ("listfonts", R_ListFonts_f);
|
||||
Cmd_AddCommand ("listskins", R_ListSkins_f);
|
||||
Cmd_AddCommand ("listskyboxes", R_ListSkyBoxes_f);
|
||||
Cmd_AddCommand ("listconfigs", R_ListConfigs_f);
|
||||
|
||||
P_InitParticleSystem();
|
||||
R_InitTextures();
|
||||
}
|
||||
|
|
|
@ -56,40 +56,41 @@ char *Skin_FindName (player_info_t *sc)
|
|||
Q_strncpyz(name, baseskin.string, sizeof(name));
|
||||
}
|
||||
|
||||
if (cl.spectator && (tracknum = Cam_TrackNum(&cl.playerview[0])) != -1)
|
||||
skinforcing_team = cl.players[tracknum].team;
|
||||
else if (cl.spectator)
|
||||
if (cl.playerview[0].cam_state == CAM_FREECAM)
|
||||
tracknum = cl.playerview[0].playernum;
|
||||
else
|
||||
tracknum = cl.playerview[0].cam_spec_track;
|
||||
|
||||
if (cl.players[tracknum].spectator)
|
||||
skinforcing_team = "spec";
|
||||
else
|
||||
skinforcing_team = cl.players[cl.playerview[0].playernum].team;
|
||||
skinforcing_team = cl.players[tracknum].team;
|
||||
|
||||
//Don't force skins in splitscreen (it's probable that the new skin would be wrong).
|
||||
//Don't force skins in TF (where skins are forced on a class basis by the mod).
|
||||
//Don't force skins in TF (where skins are already forced on a class basis by the mod).
|
||||
//Don't force skins on servers that have it disabled.
|
||||
//Don't force the local player's skin
|
||||
if (cl.splitclients<2 && !cl.teamfortress && !(cl.fpd & FPD_NO_FORCE_SKIN))
|
||||
if (&cl.players[tracknum] != sc)
|
||||
{
|
||||
char *skinname = NULL;
|
||||
// player_state_t *state;
|
||||
qboolean teammate;
|
||||
|
||||
teammate = (cl.teamplay && !strcmp(sc->team, skinforcing_team)) ? true : false;
|
||||
/*
|
||||
if (!cl.validsequence)
|
||||
goto nopowerups;
|
||||
|
||||
state = cl.frames[cl.parsecount & UPDATE_MASK].playerstate + (sc - cl.players);
|
||||
|
||||
if (state->messagenum != cl.parsecount)
|
||||
goto nopowerups;
|
||||
|
||||
if (cl.validsequence)
|
||||
{
|
||||
player_state_t *state = cl.frames[cl.parsecount & UPDATE_MASK].playerstate + (sc - cl.players);
|
||||
if (state->messagenum == cl.parsecount)
|
||||
{
|
||||
if ((state->effects & (EF_BLUE | EF_RED)) == (EF_BLUE | EF_RED))
|
||||
skinname = teammate ? cl_teambothskin.string : cl_enemybothskin.string;
|
||||
else if (state->effects & EF_BLUE)
|
||||
skinname = teammate ? cl_teamquadskin.string : cl_enemyquadskin.string;
|
||||
else if (state->effects & EF_RED)
|
||||
skinname = teammate ? cl_teampentskin.string : cl_enemypentskin.string;
|
||||
|
||||
nopowerups:
|
||||
}
|
||||
}
|
||||
*/
|
||||
if (!skinname || !skinname[0])
|
||||
skinname = teammate ? cl_teamskin.string : cl_enemyskin.string;
|
||||
|
|
|
@ -387,6 +387,8 @@ rulesetrule_t rulesetrules_strict[] = {
|
|||
{"cl_instantrotate", "0"},
|
||||
{"v_projectionmode", "0"}, /*no extended fovs*/
|
||||
{"r_shadow_realtime_world", "0"}, /*static lighting can be used to cast shadows around corners*/
|
||||
{"ruleset_allow_in", "0"},
|
||||
{"r_projection", "0"},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
|
@ -404,6 +406,8 @@ rulesetrule_t rulesetrules_nqr[] = {
|
|||
{"r_vertexlight", "0"},
|
||||
{"v_projectionmode", "0"},
|
||||
{"sbar_teamstatus", "0"},
|
||||
{"ruleset_allow_in", "0"},
|
||||
{"r_projection", "0"},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
|
|
|
@ -26,7 +26,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
#include <ctype.h> // for isdigit();
|
||||
|
||||
cvar_t ffov = SCVAR("ffov", "0");
|
||||
cvar_t r_projection = CVARD("r_projection", "0", "0: regular perspective.\n1: stereographic (aka: pannini).\n2: fisheye.\n3: panoramic.\n4: lambert azimuthal equal-area.");
|
||||
cvar_t ffov = CVARFD("ffov", "", 0, "Allows you to set a specific field of view for when a custom projection is specified. If empty, will use regular fov cvar, which might get messy.");
|
||||
#if defined(_WIN32) && !defined(MINIMAL)
|
||||
//amusing gimmick / easteregg.
|
||||
#include "winquake.h"
|
||||
|
@ -1114,6 +1115,7 @@ void V_ApplyAFov(playerview_t *pv)
|
|||
afov = scr_fov.value;
|
||||
if (pv && pv->stats[STAT_VIEWZOOM])
|
||||
afov *= pv->stats[STAT_VIEWZOOM]/255.0f;
|
||||
afov = min(afov, 170);
|
||||
|
||||
ws = 1;
|
||||
if (r_stereo_method.ival == 5 && r_stereo_separation.value)
|
||||
|
@ -1488,7 +1490,7 @@ void SCR_VRectForPlayer(vrect_t *vrect, int pnum)
|
|||
case 3:
|
||||
#ifdef GLQUAKE
|
||||
if (qrenderer == QR_OPENGL && vid.rotpixelwidth > vid.rotpixelheight * 2
|
||||
&& ffov.value >= 0 /*panoramic view always stacks player views*/
|
||||
&& r_projection.ival == 2 /*panoramic view always stacks player views*/
|
||||
)
|
||||
{ //over twice as wide as high, assume dual moniter, horizontal.
|
||||
vrect->width = vid.fbvwidth/cl.splitclients;
|
||||
|
@ -1703,7 +1705,11 @@ void R_DrawNameTags(void)
|
|||
qboolean isteam;
|
||||
char *ourteam;
|
||||
|
||||
extern cvar_t r_showfields;
|
||||
extern cvar_t r_showfields, r_projection;
|
||||
|
||||
if (r_projection.ival) //we don't actually know how to transform the points unless the projection is coded in advance. and it isn't.
|
||||
return;
|
||||
|
||||
if (r_showfields.ival && cls.allow_cheats)
|
||||
{
|
||||
world_t *w = NULL;
|
||||
|
@ -1783,7 +1789,7 @@ void R_DrawNameTags(void)
|
|||
if (cls.state != ca_active || !cl.validsequence)
|
||||
return;
|
||||
|
||||
if (r_refdef.playerview->cam_state && r_refdef.playerview->cam_spec_track >= 0)
|
||||
if (r_refdef.playerview->cam_state != CAM_FREECAM && r_refdef.playerview->cam_spec_track >= 0)
|
||||
ourteam = cl.players[r_refdef.playerview->cam_spec_track].team;
|
||||
else
|
||||
ourteam = cl.players[r_refdef.playerview->playernum].team;
|
||||
|
@ -2134,6 +2140,7 @@ void V_Init (void)
|
|||
#endif
|
||||
|
||||
Cvar_Register (&ffov, VIEWVARS);
|
||||
Cvar_Register (&r_projection, VIEWVARS);
|
||||
|
||||
BuildGammaTable (1.0, 1.0, 0.0); // no gamma yet
|
||||
Cvar_Register (&v_gamma, VIEWVARS);
|
||||
|
|
|
@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include "quakedef.h"
|
||||
#include "fs.h"
|
||||
|
||||
cvar_t ruleset_allow_in = SCVAR("ruleset_allow_in", "1");
|
||||
cvar_t rcon_level = SCVAR("rcon_level", "20");
|
||||
cvar_t cmd_maxbuffersize = SCVAR("cmd_maxbuffersize", "65536");
|
||||
cvar_t dpcompat_set = SCVAR("dpcompat_set", "0");
|
||||
|
@ -181,6 +182,58 @@ void Cmd_Wait_f (void)
|
|||
cmd_text[Cmd_ExecLevel].waitattime = realtime;
|
||||
}
|
||||
|
||||
/*
|
||||
lame timers. :s
|
||||
*/
|
||||
typedef struct cmdtimer_s {
|
||||
struct cmdtimer_s *next;
|
||||
float timer;
|
||||
int level;
|
||||
char cmdtext[1];
|
||||
} cmdtimer_t;
|
||||
static cmdtimer_t *cmdtimers;
|
||||
static void Cmd_ExecuteTimers(void)
|
||||
{
|
||||
cmdtimer_t **link, *t;
|
||||
//FIXME: we should probably insert these in order instead, then early out.
|
||||
//really, it depends on just how many we end up with
|
||||
for(link = &cmdtimers; (t = *link); )
|
||||
{
|
||||
if (t->timer < realtime)
|
||||
{
|
||||
*link = t->next;
|
||||
Cbuf_InsertText(t->cmdtext, t->level, true);
|
||||
Z_Free(t);
|
||||
}
|
||||
else
|
||||
link = &t->next;
|
||||
}
|
||||
}
|
||||
static void Cmd_In_f(void)
|
||||
{
|
||||
cmdtimer_t *n;
|
||||
float delay = atof(Cmd_Argv(1));
|
||||
char *cmd;
|
||||
if (Cmd_Argc() < 3)
|
||||
{
|
||||
Con_Printf("%s <seconds to wait> <command to execute>\n", Cmd_Argv(0));
|
||||
return;
|
||||
}
|
||||
Cmd_ShiftArgs(1, false);
|
||||
cmd = Cmd_Args();
|
||||
|
||||
if (ruleset_allow_in.ival)
|
||||
{
|
||||
n = Z_Malloc(sizeof(*n) + strlen(cmd));
|
||||
strcpy(n->cmdtext, cmd);
|
||||
n->timer = realtime + delay;
|
||||
n->level = Cmd_ExecLevel;
|
||||
|
||||
n->next = cmdtimers;
|
||||
cmdtimers = n;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cbuf_Init
|
||||
|
@ -438,6 +491,7 @@ void Cbuf_Execute (void)
|
|||
cmd_text[RESTRICT_LOCAL].waitattime = realtime;
|
||||
}
|
||||
#endif
|
||||
Cmd_ExecuteTimers();
|
||||
|
||||
for (level = 0; level < sizeof(cmd_text)/sizeof(cmd_text[0]); level++)
|
||||
if (cmd_text[level].buf.cursize)
|
||||
|
@ -3263,6 +3317,9 @@ void Cmd_Init (void)
|
|||
|
||||
Cvar_Register(&tp_disputablemacros, "Teamplay");
|
||||
|
||||
Cvar_Register(&ruleset_allow_in, "Console");
|
||||
Cmd_AddCommandD ("in", Cmd_In_f, "Issues the given command after a time delay. Disabled if ruleset_allow_in is 0.");
|
||||
|
||||
Cvar_Register(&dpcompat_set, "Darkplaces compatibility");
|
||||
Cvar_Register (&cl_warncmd, "Warnings");
|
||||
Cvar_Register (&cfg_save_all, "client operation options");
|
||||
|
|
|
@ -1386,38 +1386,43 @@ qboolean R_RenderScene_Cubemap(void)
|
|||
|
||||
shader_t *shader;
|
||||
int facemask;
|
||||
extern cvar_t r_projection;
|
||||
|
||||
/*needs glsl*/
|
||||
if (!gl_config.arb_shader_objects)
|
||||
return false;
|
||||
if (!ffov.value)
|
||||
return false;
|
||||
if (!cls.allow_postproc)
|
||||
return false;
|
||||
|
||||
if (!*ffov.string || !strcmp(ffov.string, "0"))
|
||||
ffov.value = scr_fov.value;
|
||||
|
||||
facemask = 0;
|
||||
if (ffov.value < 0)
|
||||
switch(r_projection.ival)
|
||||
{
|
||||
shader = R_RegisterShader("postproc_panorama", SUF_NONE,
|
||||
default: //invalid.
|
||||
return false;
|
||||
case 1:
|
||||
shader = R_RegisterShader("postproc_stereographic", SUF_NONE,
|
||||
"{\n"
|
||||
"program postproc_panorama\n"
|
||||
"program postproc_stereographic\n"
|
||||
"{\n"
|
||||
"map $sourcecube\n"
|
||||
"}\n"
|
||||
"}\n"
|
||||
);
|
||||
|
||||
//panoramic view needs at most the four sides
|
||||
facemask |= 1<<4; /*front view*/
|
||||
if (ffov.value < -90)
|
||||
if (ffov.value > 70)
|
||||
{
|
||||
facemask |= (1<<0) | (1<<1); /*side views*/
|
||||
if (ffov.value < -270)
|
||||
facemask |= (1<<0) | (1<<1); /*side/top*/
|
||||
if (ffov.value > 85)
|
||||
facemask |= (1<<2) | (1<<3); /*bottom views*/
|
||||
if (ffov.value > 300)
|
||||
facemask |= 1<<5; /*back view*/
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
case 2:
|
||||
shader = R_RegisterShader("postproc_fisheye", SUF_NONE,
|
||||
"{\n"
|
||||
"program postproc_fisheye\n"
|
||||
|
@ -1433,7 +1438,47 @@ qboolean R_RenderScene_Cubemap(void)
|
|||
facemask |= (1<<0) | (1<<1) | (1<<2) | (1<<3); /*side/top/bottom views*/
|
||||
if (ffov.value > 270)
|
||||
facemask |= 1<<5; /*back view*/
|
||||
break;
|
||||
case 3:
|
||||
shader = R_RegisterShader("postproc_panorama", SUF_NONE,
|
||||
"{\n"
|
||||
"program postproc_panorama\n"
|
||||
"{\n"
|
||||
"map $sourcecube\n"
|
||||
"}\n"
|
||||
"}\n"
|
||||
);
|
||||
|
||||
//panoramic view needs at most the four sides
|
||||
facemask |= 1<<4; /*front view*/
|
||||
if (ffov.value > 90)
|
||||
{
|
||||
facemask |= (1<<0) | (1<<1); /*side views*/
|
||||
if (ffov.value > 270)
|
||||
facemask |= 1<<5; /*back view*/
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
shader = R_RegisterShader("postproc_laea", SUF_NONE,
|
||||
"{\n"
|
||||
"program postproc_laea\n"
|
||||
"{\n"
|
||||
"map $sourcecube\n"
|
||||
"}\n"
|
||||
"}\n"
|
||||
);
|
||||
|
||||
facemask |= 1<<4; /*front view*/
|
||||
if (ffov.value > 90)
|
||||
{
|
||||
facemask |= (1<<0) | (1<<1) | (1<<2) | (1<<3); /*side/top/bottom views*/
|
||||
if (ffov.value > 270)
|
||||
facemask |= 1<<5; /*back view*/
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
//FIXME: we should be able to rotate the view
|
||||
|
||||
vrect = r_refdef.vrect;
|
||||
prect = r_refdef.pxrect;
|
||||
|
@ -1494,6 +1539,9 @@ qboolean R_RenderScene_Cubemap(void)
|
|||
ang[1][1] = 90;
|
||||
ang[1][2] = saveang[0];
|
||||
ang[5][0] = -saveang[0]*2;
|
||||
//in theory, we could use a geometry shader to duplicate the polygons to each face.
|
||||
//that would of course require that every bit of glsl had such a geometry shader.
|
||||
//it would at least reduce cpu load quite a bit.
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
if (!(facemask & (1<<i)))
|
||||
|
@ -1532,7 +1580,16 @@ qboolean R_RenderScene_Cubemap(void)
|
|||
qglLoadIdentity ();
|
||||
*/
|
||||
// draw it through the shader
|
||||
R2D_Image(0, 0, vid.width, vid.height, -0.5, 0.5, 0.5, -0.5, shader);
|
||||
if (vrect.width > vrect.height)
|
||||
{
|
||||
float aspect = (0.5 * vrect.height) / vrect.width;
|
||||
R2D_Image(0, 0, vid.width, vid.height, -0.5, aspect, 0.5, -aspect, shader);
|
||||
}
|
||||
else
|
||||
{
|
||||
float aspect = (0.5 * vrect.width) / vrect.height;
|
||||
R2D_Image(0, 0, vid.width, vid.height, -aspect, 0.5, aspect, -0.5, shader);
|
||||
}
|
||||
|
||||
//revert the matricies
|
||||
/* qglMatrixMode(GL_PROJECTION);
|
||||
|
@ -1624,7 +1681,8 @@ void GLR_RenderView (void)
|
|||
}
|
||||
if (r_refdef.flags & RDF_UNDERWATER)
|
||||
{
|
||||
if (!r_waterwarp.value)
|
||||
extern cvar_t r_projection;
|
||||
if (!r_waterwarp.value || r_projection.ival)
|
||||
r_refdef.flags &= ~RDF_UNDERWATER; //no warp at all
|
||||
else if (r_waterwarp.value > 0 && scenepp_waterwarp)
|
||||
r_refdef.flags |= RDF_WATERWARP; //try fullscreen warp instead if we can
|
||||
|
|
|
@ -33,7 +33,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
extern texid_t missing_texture;
|
||||
texid_t r_whiteimage;
|
||||
static qboolean shader_reload_needed;
|
||||
qboolean shader_reload_needed;
|
||||
static qboolean shader_rescan_needed;
|
||||
static char **saveshaderbody;
|
||||
|
||||
|
@ -5678,6 +5678,10 @@ void Shader_DoReload(void)
|
|||
int oldsort;
|
||||
qboolean resort = false;
|
||||
|
||||
//don't spam shader reloads while we're connecting, as that's just wasteful.
|
||||
if (cls.state && cls.state < ca_active)
|
||||
return;
|
||||
|
||||
if (shader_rescan_needed)
|
||||
{
|
||||
Shader_FlushCache();
|
||||
|
|
|
@ -125,7 +125,7 @@ void (APIENTRY *qglNormal3fv) (const GLfloat *v);
|
|||
void (APIENTRY *qglMatrixMode) (GLenum mode);
|
||||
void (APIENTRY *qglMultMatrixf) (const GLfloat *m);
|
||||
void (APIENTRY *qglNewList) (GLuint list, GLenum mode);
|
||||
void (APIENTRY *qglOrtho) (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
|
||||
//void (APIENTRY *qglOrtho) (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
|
||||
void (APIENTRY *qglPolygonMode) (GLenum face, GLenum mode);
|
||||
void (APIENTRY *qglPopMatrix) (void);
|
||||
void (APIENTRY *qglPushMatrix) (void);
|
||||
|
@ -2333,7 +2333,7 @@ static void GLSlang_ProgAutoFields(program_t *prog, char **cvarnames, int *cvart
|
|||
cvar = Cvar_Get(tmpname, tmpval, CVAR_SHADERSYSTEM, "glsl cvars");
|
||||
if (!cvar)
|
||||
continue;
|
||||
cvar->flags |= CVAR_SHADERSYSTEM;
|
||||
// cvar->flags |= CVAR_SHADERSYSTEM;
|
||||
prog->parm[prog->numparams].type = cvartypes[i];
|
||||
prog->parm[prog->numparams].pval = cvar;
|
||||
found = false;
|
||||
|
@ -2485,7 +2485,7 @@ void GL_Init(void *(*getglfunction) (char *name))
|
|||
qglNormal3fv = (void *)getglcore("glNormal3fv");
|
||||
qglMatrixMode = (void *)getglcore("glMatrixMode");
|
||||
qglMultMatrixf = (void *)getglcore("glMultMatrixf");
|
||||
qglOrtho = (void *)getglcore("glOrtho");
|
||||
// qglOrtho = (void *)getglcore("glOrtho");
|
||||
qglPolygonMode = (void *)getglcore("glPolygonMode");
|
||||
qglPopMatrix = (void *)getglcore("glPopMatrix");
|
||||
qglPushMatrix = (void *)getglcore("glPushMatrix");
|
||||
|
|
|
@ -894,7 +894,7 @@ extern void (APIENTRY *qglNormal3iv) (const GLint *v);
|
|||
extern void (APIENTRY *qglNormal3s) (GLshort nx, GLshort ny, GLshort nz);
|
||||
extern void (APIENTRY *qglNormal3sv) (const GLshort *v);
|
||||
extern void (APIENTRY *qglNormalPointer) (GLenum type, GLsizei stride, const GLvoid *pointer);
|
||||
extern void (APIENTRY *qglOrtho) (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
|
||||
//extern void (APIENTRY *qglOrtho) (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
|
||||
extern void (APIENTRY *qglPassThrough) (GLfloat token);
|
||||
extern void (APIENTRY *qglPixelMapfv) (GLenum map, GLsizei mapsize, const GLfloat *values);
|
||||
extern void (APIENTRY *qglPixelMapuiv) (GLenum map, GLsizei mapsize, const GLuint *values);
|
||||
|
|
|
@ -1578,7 +1578,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
"nst = (1.0 + nst) / 2.0;\n"
|
||||
"vec4 l = texture2D(s_t0, nst)*5.0;\n"
|
||||
"vec4 c = texture2D(s_t1, tc);\n"
|
||||
"vec3 lmsamp = texture2D(s_t2, lm).rgb*e_lmscale;\n"
|
||||
"vec3 lmsamp = texture2D(s_t2, lm).rgb*e_lmscale.rgb;\n"
|
||||
"vec3 diff = l.rgb;\n"
|
||||
"vec3 chrom = diff / (0.001 + dot(diff, vec3(0.3, 0.59, 0.11)));\n"
|
||||
"vec3 spec = chrom * l.a;\n"
|
||||
|
@ -1645,10 +1645,100 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
"{\n"
|
||||
"vec3 tc; \n"
|
||||
"float ang; \n"
|
||||
"ang = texcoord.x*-radians(cvar_ffov); \n"
|
||||
"ang = texcoord.x*radians(cvar_ffov); \n"
|
||||
"tc.x = sin(ang); \n"
|
||||
"tc.y = -texcoord.y; \n"
|
||||
"tc.z = cos(ang); \n"
|
||||
"gl_FragColor = textureCube(s_t0, tc);\n"
|
||||
"}\n"
|
||||
"#endif\n"
|
||||
},
|
||||
#endif
|
||||
#ifdef GLQUAKE
|
||||
{QR_OPENGL, 110, "postproc_laea",
|
||||
"!!cvarf ffov\n"
|
||||
|
||||
//my attempt at lambert azimuthal equal-area view rendering, because you'll remember that name easily.
|
||||
|
||||
"#ifdef VERTEX_SHADER\n"
|
||||
"attribute vec2 v_texcoord;\n"
|
||||
"varying vec2 texcoord;\n"
|
||||
"uniform float cvar_ffov;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
"texcoord = v_texcoord.xy;\n"
|
||||
|
||||
//make sure the ffov cvar actually does something meaningful
|
||||
"texcoord *= cvar_ffov / 90.0;\n"
|
||||
|
||||
"gl_Position = ftetransform();\n"
|
||||
"}\n"
|
||||
"#endif\n"
|
||||
"#ifdef FRAGMENT_SHADER\n"
|
||||
"uniform samplerCube s_t0;\n"
|
||||
"varying vec2 texcoord;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
"vec3 tc; \n"
|
||||
"vec2 d; \n"
|
||||
"vec2 ang; \n"
|
||||
"d = texcoord; \n"
|
||||
|
||||
//compute the 2d->3d projection
|
||||
"float sq = d.x*d.x+d.y*d.y;\n"
|
||||
"if (sq > 4.0)\n"
|
||||
"gl_FragColor = vec4(0,0,0,1);\n"
|
||||
"else\n"
|
||||
"{\n"
|
||||
"tc.x = sqrt(1.0-(sq/4.0))*d.x;\n"
|
||||
"tc.y = sqrt(1.0-(sq/4.0))*d.y;\n"
|
||||
"tc.z = -1.0 + (sq/2.0);\n"
|
||||
|
||||
"tc.y *= -1.0;\n"
|
||||
"tc.z *= -1.0;\n"
|
||||
|
||||
"gl_FragColor = textureCube(s_t0, tc);\n"
|
||||
"}\n"
|
||||
"}\n"
|
||||
"#endif\n"
|
||||
},
|
||||
#endif
|
||||
#ifdef GLQUAKE
|
||||
{QR_OPENGL, 110, "postproc_stereographic",
|
||||
"!!cvarf ffov\n"
|
||||
|
||||
//stereographic view rendering, for high fovs that are still playable.
|
||||
|
||||
"#ifdef VERTEX_SHADER\n"
|
||||
"attribute vec2 v_texcoord;\n"
|
||||
"varying vec2 texcoord;\n"
|
||||
"uniform float cvar_ffov;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
"texcoord = v_texcoord.xy;\n"
|
||||
|
||||
//make sure the ffov cvar actually does something meaningful
|
||||
"texcoord *= cvar_ffov / 90.0;\n"
|
||||
|
||||
"gl_Position = ftetransform();\n"
|
||||
"}\n"
|
||||
"#endif\n"
|
||||
"#ifdef FRAGMENT_SHADER\n"
|
||||
"uniform samplerCube s_t0;\n"
|
||||
"varying vec2 texcoord;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
"vec3 tc; \n"
|
||||
"vec2 d; \n"
|
||||
"vec2 ang; \n"
|
||||
"d = texcoord; \n"
|
||||
|
||||
//compute the 2d->3d projection
|
||||
"float div = 1.0 + d.x*d.x + d.y*d.y;\n"
|
||||
"tc.x = 2.0*d.x/div;\n"
|
||||
"tc.y = -2.0*d.y/div;\n"
|
||||
"tc.z = -(-1.0 + d.x*d.x + d.y*d.y)/div;\n"
|
||||
|
||||
"gl_FragColor = textureCube(s_t0, tc);\n"
|
||||
"}\n"
|
||||
"#endif\n"
|
||||
|
|
|
@ -27,6 +27,8 @@ char shaders[][64] =
|
|||
"lpp_wall",
|
||||
"postproc_fisheye",
|
||||
"postproc_panorama",
|
||||
"postproc_laea",
|
||||
"postproc_stereographic",
|
||||
"rtlight",
|
||||
"underwaterwarp",
|
||||
"menutint",
|
||||
|
|
45
engine/shaders/glsl/postproc_laea.glsl
Normal file
45
engine/shaders/glsl/postproc_laea.glsl
Normal file
|
@ -0,0 +1,45 @@
|
|||
!!cvarf ffov
|
||||
|
||||
//my attempt at lambert azimuthal equal-area view rendering, because you'll remember that name easily.
|
||||
|
||||
#ifdef VERTEX_SHADER
|
||||
attribute vec2 v_texcoord;
|
||||
varying vec2 texcoord;
|
||||
uniform float cvar_ffov;
|
||||
void main()
|
||||
{
|
||||
texcoord = v_texcoord.xy;
|
||||
|
||||
//make sure the ffov cvar actually does something meaningful
|
||||
texcoord *= cvar_ffov / 90.0;
|
||||
|
||||
gl_Position = ftetransform();
|
||||
}
|
||||
#endif
|
||||
#ifdef FRAGMENT_SHADER
|
||||
uniform samplerCube s_t0;
|
||||
varying vec2 texcoord;
|
||||
void main()
|
||||
{
|
||||
vec3 tc;
|
||||
vec2 d;
|
||||
vec2 ang;
|
||||
d = texcoord;
|
||||
|
||||
//compute the 2d->3d projection
|
||||
float sq = d.x*d.x+d.y*d.y;
|
||||
if (sq > 4.0)
|
||||
gl_FragColor = vec4(0,0,0,1);
|
||||
else
|
||||
{
|
||||
tc.x = sqrt(1.0-(sq/4.0))*d.x;
|
||||
tc.y = sqrt(1.0-(sq/4.0))*d.y;
|
||||
tc.z = -1.0 + (sq/2.0);
|
||||
|
||||
tc.y *= -1.0;
|
||||
tc.z *= -1.0;
|
||||
|
||||
gl_FragColor = textureCube(s_t0, tc);
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -19,7 +19,7 @@ void main()
|
|||
{
|
||||
vec3 tc;
|
||||
float ang;
|
||||
ang = texcoord.x*-radians(cvar_ffov);
|
||||
ang = texcoord.x*radians(cvar_ffov);
|
||||
tc.x = sin(ang);
|
||||
tc.y = -texcoord.y;
|
||||
tc.z = cos(ang);
|
||||
|
|
37
engine/shaders/glsl/postproc_stereographic.glsl
Normal file
37
engine/shaders/glsl/postproc_stereographic.glsl
Normal file
|
@ -0,0 +1,37 @@
|
|||
!!cvarf ffov
|
||||
|
||||
//stereographic view rendering, for high fovs that are still playable.
|
||||
|
||||
#ifdef VERTEX_SHADER
|
||||
attribute vec2 v_texcoord;
|
||||
varying vec2 texcoord;
|
||||
uniform float cvar_ffov;
|
||||
void main()
|
||||
{
|
||||
texcoord = v_texcoord.xy;
|
||||
|
||||
//make sure the ffov cvar actually does something meaningful
|
||||
texcoord *= cvar_ffov / 90.0;
|
||||
|
||||
gl_Position = ftetransform();
|
||||
}
|
||||
#endif
|
||||
#ifdef FRAGMENT_SHADER
|
||||
uniform samplerCube s_t0;
|
||||
varying vec2 texcoord;
|
||||
void main()
|
||||
{
|
||||
vec3 tc;
|
||||
vec2 d;
|
||||
vec2 ang;
|
||||
d = texcoord;
|
||||
|
||||
//compute the 2d->3d projection
|
||||
float div = 1.0 + d.x*d.x + d.y*d.y;
|
||||
tc.x = 2.0*d.x/div;
|
||||
tc.y = -2.0*d.y/div;
|
||||
tc.z = -(-1.0 + d.x*d.x + d.y*d.y)/div;
|
||||
|
||||
gl_FragColor = textureCube(s_t0, tc);
|
||||
}
|
||||
#endif
|
Loading…
Reference in a new issue