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:
Spoike 2015-07-03 02:07:41 +00:00
parent 667e8dec10
commit a85f3c5c71
22 changed files with 463 additions and 73 deletions

View File

@ -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();
}
}

View File

@ -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;
CL_ProgressDemoTime();
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)

View File

@ -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;

View File

@ -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

View File

@ -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;
}
Cvar_ForceSet(var, "10");
//highs are capped elsewhere. this allows fisheye to use this cvar automatically.
}
void QDECL SCR_Viewsize_Callback (struct cvar_s *var, char *oldvalue)

View File

@ -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];

View File

@ -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)
{

View File

@ -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."),

View File

@ -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();
}

View File

@ -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 ((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 (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;
}
}
*/
if (!skinname || !skinname[0])
skinname = teammate ? cl_teamskin.string : cl_enemyskin.string;

View File

@ -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}
};

View File

@ -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);

View File

@ -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");

View File

@ -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,8 +1438,48 @@ 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;
// prect.x = (vrect.x * vid.pixelwidth)/vid.width;
@ -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

View File

@ -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();

View File

@ -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");

View File

@ -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);

View File

@ -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"

View File

@ -27,6 +27,8 @@ char shaders[][64] =
"lpp_wall",
"postproc_fisheye",
"postproc_panorama",
"postproc_laea",
"postproc_stereographic",
"rtlight",
"underwaterwarp",
"menutint",

View 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

View File

@ -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);

View 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