Small tweeks, bugfixes, breakages, cleanups...

Added $reflection texture map for (water) shaders. Just renders the screen to an fbo before rendering the surface.
hub/savegame fixes.


git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4034 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2012-05-09 15:30:53 +00:00
parent 7b5a5f6f9e
commit 33a540806e
105 changed files with 3323 additions and 1713 deletions

View file

@ -530,7 +530,7 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
Cbuf_AddText(VM_POINTER(arg[0]), RESTRICT_SERVER);
break;
case CG_ADDCOMMAND:
Cmd_AddRemCommand(VM_POINTER(arg[0]), NULL);
Cmd_AddCommand(VM_POINTER(arg[0]), NULL);
break;
case CG_SENDCLIENTCOMMAND:
Con_DPrintf("CG_SENDCLIENTCOMMAND: %s", (char*)VM_POINTER(arg[0]));

View file

@ -842,8 +842,6 @@ void CL_Stop_f (void)
cls.demooutfile = NULL;
cls.demorecording = false;
Con_Printf ("Completed demo\n");
FS_FlushFSHash();
}
@ -1404,7 +1402,6 @@ void CL_PlayDownloadedDemo(char *name, qboolean success)
Con_Printf("Failed to download %s\n", name);
else
{
FS_FlushFSHash();
Cbuf_AddText(va("playdemo %s\n", name), RESTRICT_LOCAL);
}
}

View file

@ -1250,10 +1250,7 @@ qboolean CL_SendCmdQ2 (sizebuf_t *buf)
else
MSG_WriteLong (buf, cl.q2frame.serverframe);
if (R_LightPoint)
lightlev = R_LightPoint(cl.simorg[0]);
else
lightlev = 255;
lightlev = R_LightPoint(cl.simorg[0]);
// msecs = msecs - (double)msecstouse;

View file

@ -542,7 +542,7 @@ void CL_SendConnectPacket (int mtu,
if (mtu > 0)
{
if (adr.type == NA_LOOPBACK)
mtu = 8192;
mtu = MAX_UDP_PACKET;
else if (net_mtu.ival > 64 && mtu > net_mtu.ival)
mtu = net_mtu.ival;
mtu &= ~7;
@ -3094,6 +3094,9 @@ void CL_Init (void)
#endif
#ifdef CSQC_DAT
CSQC_RegisterCvarsAndThings();
#endif
#if defined(CSQC_DAT) || defined(MENU_DAT)
PF_Common_RegisterCvars();
#endif
Cvar_Register (&host_speeds, cl_controlgroup);
Cvar_Register (&developer, cl_controlgroup);
@ -3823,6 +3826,9 @@ void Host_Init (quakeparms_t *parms)
CDAudio_Init ();
Sbar_Init ();
CL_Init ();
#if defined(SERVERONLY) || !(defined(CSQC_DAT) || defined(MENU_DAT))
PF_Common_RegisterCvars();
#endif
TranslateInit();
#ifndef CLIENTONLY
@ -4021,7 +4027,7 @@ void Host_Shutdown(void)
UI_Stop();
#endif
Host_WriteConfiguration ();
// Host_WriteConfiguration ();
CDAudio_Shutdown ();
S_Shutdown();

View file

@ -953,6 +953,7 @@ int CL_LoadModels(int stage, qboolean dontactuallyload)
if (cls.protocol == CP_NETQUAKE && !cl_nocsqc.ival && !cls.demoplayback)
{
char *s;
SCR_SetLoadingFile("csprogs");
s = Info_ValueForKey(cl.serverinfo, "*csprogs");
if (*s) //only allow csqc if the server says so, and the 'checksum' matches.
{
@ -977,6 +978,7 @@ int CL_LoadModels(int stage, qboolean dontactuallyload)
#ifdef HLCLIENT
if (atstage())
{
SCR_SetLoadingFile("hlclient");
CLHL_LoadClientGame();
endstage();
}
@ -996,6 +998,7 @@ int CL_LoadModels(int stage, qboolean dontactuallyload)
if (anycsqc || *s || cls.demoplayback) //only allow csqc if the server says so, and the 'checksum' matches.
{
unsigned int chksum = strtoul(s, NULL, 0);
SCR_SetLoadingFile("csprogs");
if (!CSQC_Init(anycsqc, chksum))
{
Sbar_Start(); //try and start this before we're actually on the server,
@ -1010,6 +1013,7 @@ int CL_LoadModels(int stage, qboolean dontactuallyload)
if (atstage())
{
SCR_SetLoadingFile("prenewmap");
loadmodel = cl.worldmodel;
if (R_PreNewMap)
@ -1031,6 +1035,7 @@ int CL_LoadModels(int stage, qboolean dontactuallyload)
if (atstage())
{
SCR_SetLoadingFile(cl.model_name[i]);
#ifdef CSQC_DAT
if (i == 1)
CSQC_LoadResource(cl.model_name[i], "map");
@ -1057,6 +1062,7 @@ int CL_LoadModels(int stage, qboolean dontactuallyload)
if (atstage())
{
SCR_SetLoadingFile(cl.model_name_vwep[i]);
#ifdef CSQC_DAT
CSQC_LoadResource(cl.model_name_vwep[i], "vwep");
#endif
@ -1080,6 +1086,8 @@ int CL_LoadModels(int stage, qboolean dontactuallyload)
// Host_EndGame("Worldmodel wasn't loaded\n");
}
SCR_SetLoadingFile("csprogs world");
#ifdef CSQC_DAT
CSQC_WorldLoaded();
#endif
@ -1093,6 +1101,7 @@ int CL_LoadModels(int stage, qboolean dontactuallyload)
continue;
if (atstage())
{
SCR_SetLoadingFile(cl.model_csqcname[i]);
#ifdef CSQC_DAT
if (i == 1)
CSQC_LoadResource(cl.model_csqcname[i], "map");
@ -1110,6 +1119,7 @@ int CL_LoadModels(int stage, qboolean dontactuallyload)
if (atstage())
{
SCR_SetLoadingFile("wads");
Wad_NextDownload();
endstage();
@ -1117,6 +1127,7 @@ int CL_LoadModels(int stage, qboolean dontactuallyload)
if (atstage())
{
SCR_SetLoadingFile("external textures");
loadmodel = cl.worldmodel;
// if (!loadmodel || loadmodel->type == mod_dummy)
// Host_EndGame("No worldmodel was loaded\n");
@ -1129,6 +1140,7 @@ int CL_LoadModels(int stage, qboolean dontactuallyload)
// all done
if (atstage())
{
SCR_SetLoadingFile("newmap");
loadmodel = cl.worldmodel;
// if (!loadmodel || loadmodel->type == mod_dummy)
// Host_EndGame("No worldmodel was loaded\n");
@ -1143,6 +1155,7 @@ int CL_LoadModels(int stage, qboolean dontactuallyload)
#ifdef CSQC_DAT
if (atstage())
{
SCR_SetLoadingFile("csqc init");
if (CSQC_Inited())
{
CL_SendClientCommand(true, "enablecsqc");
@ -1174,6 +1187,7 @@ int CL_LoadSounds(int stage, qboolean dontactuallyload)
if (atstage())
{
SCR_SetLoadingFile(cl.sound_name[i]);
#ifdef CSQC_DAT
CSQC_LoadResource(cl.sound_name[i], "sound");
#endif
@ -1346,7 +1360,7 @@ void CL_RequestNextDownload (void)
current_loading_size = cl.contentstage;
if (stage < 0)
return;
SCR_SetLoadingFile("prespawn");
cl.sendprespawn = false;
#ifdef warningmsg
#pragma warningmsg("timedemo timer should start here")
@ -1989,7 +2003,6 @@ void CLDP_ParseDownloadFinished(char *s)
Cmd_TokenizeString(s+1, false, false);
VFS_CLOSE (cls.downloadqw);
FS_FlushFSHash();
cls.downloadqw = FS_OpenVFS (cls.downloadtempname, "rb", FS_GAME);
if (cls.downloadqw)

View file

@ -221,12 +221,14 @@ cvar_t show_gameclock_y = SCVAR("cl_gameclock_y", "-1");
cvar_t show_speed = SCVAR("show_speed", "0");
cvar_t show_speed_x = SCVAR("show_speed_x", "-1");
cvar_t show_speed_y = SCVAR("show_speed_y", "-9");
cvar_t scr_loadingrefresh = SCVAR("scr_loadingrefresh", "0");
extern char cl_screengroup[];
void CLSCR_Init(void)
{
Cmd_AddCommand("cprint", SCR_CPrint_f);
Cvar_Register(&scr_loadingrefresh, cl_screengroup);
Cvar_Register(&show_fps, cl_screengroup);
Cvar_Register(&show_fps_x, cl_screengroup);
Cvar_Register(&show_fps_y, cl_screengroup);
@ -1137,9 +1139,9 @@ void SCR_Init (void)
//
// register our commands
//
Cmd_AddRemCommand ("screenshot",SCR_ScreenShot_f);
Cmd_AddRemCommand ("sizeup",SCR_SizeUp_f);
Cmd_AddRemCommand ("sizedown",SCR_SizeDown_f);
Cmd_AddCommand ("screenshot",SCR_ScreenShot_f);
Cmd_AddCommand ("sizeup",SCR_SizeUp_f);
Cmd_AddCommand ("sizedown",SCR_SizeDown_f);
scr_net = R2D_SafePicFromWad ("net");
scr_turtle = R2D_SafePicFromWad ("turtle");
@ -1446,6 +1448,7 @@ SCR_DrawLoading
*/
int total_loading_size, current_loading_size, loading_stage;
char *loadingfile;
int CL_DownloadRate(void);
int SCR_GetLoadingStage(void)
@ -1454,8 +1457,39 @@ int SCR_GetLoadingStage(void)
}
void SCR_SetLoadingStage(int stage)
{
switch(stage)
{
case LS_NONE:
if (loadingfile)
Z_Free(loadingfile);
loadingfile = NULL;
break;
case LS_CONNECTION:
SCR_SetLoadingFile("connection...");
break;
case LS_SERVER:
if (scr_con_current > vid.height*scr_consize.value)
scr_con_current = vid.height*scr_consize.value;
SCR_SetLoadingFile("server...");
break;
case LS_CLIENT:
SCR_SetLoadingFile("initial state");
break;
}
loading_stage = stage;
}
void SCR_SetLoadingFile(char *str)
{
if (loadingfile)
Z_Free(loadingfile);
loadingfile = Z_Malloc(strlen(str)+1);
strcpy(loadingfile, str);
if (scr_loadingrefresh.ival)
{
SCR_UpdateScreen();
}
}
void SCR_DrawLoading (void)
{
@ -1520,9 +1554,11 @@ void SCR_DrawLoading (void)
Draw_FunString(x+8, y+4, va("Loading %s... %i%%",
(loading_stage == LS_SERVER) ? "server" : "client",
current_loading_size * 100 / total_loading_size));
y += 16;
}
y += 16;
if (loadingfile)
Draw_FunString(x+8, y+4, loadingfile);
}
else
{ //hexen2 files

View file

@ -170,7 +170,6 @@ typedef enum
#define Q2SPLASH_BLOOD 6
#endif
#define MAX_BEAMS 64
typedef struct
{
int entity;
@ -188,9 +187,9 @@ typedef struct
trailstate_t *emitstate;
} beam_t;
beam_t cl_beams[MAX_BEAMS];
beam_t *cl_beams;
int cl_beams_max;
#define MAX_EXPLOSIONS 256
typedef struct
{
vec3_t origin;
@ -212,7 +211,8 @@ typedef struct
int skinnum;
} explosion_t;
explosion_t cl_explosions[MAX_EXPLOSIONS];
explosion_t *cl_explosions;
int cl_explosions_max;
static int explosions_running;
static int beams_running;
@ -513,8 +513,13 @@ CL_ClearTEnts
*/
void CL_ClearTEnts (void)
{
memset (&cl_beams, 0, sizeof(cl_beams));
memset (&cl_explosions, 0, sizeof(cl_explosions));
cl_beams_max = 0;
BZ_Free(cl_beams);
cl_beams = NULL;
cl_explosions_max = 0;
BZ_Free(cl_explosions);
cl_explosions = NULL;
}
static void CL_ClearExplosion(explosion_t *exp)
@ -549,8 +554,14 @@ explosion_t *CL_AllocExplosion (void)
}
}
if (i == explosions_running && i != MAX_EXPLOSIONS)
// if (i == explosions_running && i < cl_maxexplosions.ival)
{
if (i == cl_explosions_max)
{
cl_explosions_max = (i+1)*2;
cl_explosions = BZ_Realloc(cl_explosions, sizeof(*cl_explosions)*cl_explosions_max);
}
explosions_running++;
CL_ClearExplosion(&cl_explosions[i]);
return &cl_explosions[i];
@ -560,7 +571,7 @@ explosion_t *CL_AllocExplosion (void)
time = cl.time;
index = 0;
for (i=0 ; i<MAX_EXPLOSIONS ; i++)
for (i=0 ; i<cl_explosions_max ; i++)
if (cl_explosions[i].start < time)
{
time = cl_explosions[i].start;
@ -601,8 +612,14 @@ beam_t *CL_NewBeam (int entity, int tag)
}
}
if (i == beams_running && i != MAX_BEAMS)
// if (i == beams_running && i < cl_maxbeams.ival)
{
if (i == cl_beams_max)
{
cl_beams_max = (i+1)*2;
cl_beams = BZ_Realloc(cl_beams, cl_beams_max*sizeof(*cl_beams));
}
beams_running++;
cl_beams[i].active = true;
return &cl_beams[i];

View file

@ -825,6 +825,7 @@ MMRESULT (WINAPI *qacmStreamUnprepareHeader) (HACMSTREAM has, LPACMSTREAMHEADER
MMRESULT (WINAPI *qacmStreamConvert) (HACMSTREAM has, LPACMSTREAMHEADER pash, DWORD fdwConvert);
MMRESULT (WINAPI *qacmStreamPrepareHeader) (HACMSTREAM has, LPACMSTREAMHEADER pash, DWORD fdwPrepare);
MMRESULT (WINAPI *qacmStreamOpen) (LPHACMSTREAM phas, HACMDRIVER had, LPWAVEFORMATEX pwfxSrc, LPWAVEFORMATEX pwfxDst, LPWAVEFILTER pwfltr, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen);
MMRESULT (WINAPI *qacmStreamClose) (HACMSTREAM has, DWORD fdwClose);
static qboolean qacmStartup(void)
{
@ -838,6 +839,7 @@ static qboolean qacmStartup(void)
{(void*)&qacmStreamConvert, "acmStreamConvert"},
{(void*)&qacmStreamPrepareHeader, "acmStreamPrepareHeader"},
{(void*)&qacmStreamOpen, "acmStreamOpen"},
{(void*)&qacmStreamClose, "acmStreamClose"},
{NULL,NULL}
};
inited = true;
@ -3149,7 +3151,7 @@ void Media_Init(void)
Cvar_Register(&capturesoundbits, "AVI capture controls");
Cvar_Register(&capturesoundchannels, "AVI capture controls");
S_RegisterSoundInputPlugin(S_LoadMP3Sound);
// S_RegisterSoundInputPlugin(S_LoadMP3Sound);
#endif
#endif
@ -3181,6 +3183,18 @@ typedef struct
qbyte srcdata[1];
} mp3decoder_t;
void S_MP3_Abort(sfx_t *sfx)
{
mp3decoder_t *dec = sfx->decoder.buf;
sfx->decoder.buf = NULL;
qacmStreamClose(dec->acm, 0);
if (dec->dstdata)
BZ_Free(dec->dstdata);
BZ_Free(dec);
}
/*must be thread safe*/
sfxcache_t *S_MP3_Locate(sfx_t *sfx, sfxcache_t *buf, int start, int length)
{
@ -3204,6 +3218,12 @@ sfxcache_t *S_MP3_Locate(sfx_t *sfx, sfxcache_t *buf, int start, int length)
if (dec->dstcount > snd_speed*6)
{
int trim = dec->dstcount - snd_speed; //retain a second of buffer in case we have multiple sound devices
if (dec->dststart + trim > start)
{
trim = start - dec->dststart;
if (trim < 0)
trim = 0;
}
// if (trim < 0)
// trim = 0;
/// if (trim > dec->dstcount)
@ -3298,7 +3318,7 @@ qboolean S_LoadMP3Sound (sfx_t *s, qbyte *data, int datalen, int sndspeed)
memcpy(dec->srcdata, data, datalen);
dec->srclen = datalen;
s->decoder.buf = dec;
s->decoder.abort = NULL;
s->decoder.abort = S_MP3_Abort;
s->decoder.decodedata = S_MP3_Locate;
dec->dstdata = NULL;

View file

@ -822,7 +822,7 @@ qboolean M_VideoApplyShadowLighting (union menuoption_s *op,struct menu_s *menu,
char *cvarvd = "0";
char *cvarsrd = "0";
char *cvarsrds = "0";
switch (info->lightcombo->selectedoption)
switch (info->dlightcombo->selectedoption)
{
case 1:
cvard = "1";

View file

@ -865,62 +865,62 @@ void M_Init_Internal (void)
internalmenusregistered = true;
#ifndef CLIENTONLY
Cmd_AddRemCommand ("menu_save", M_Menu_Save_f);
Cmd_AddRemCommand ("menu_load", M_Menu_Load_f);
Cmd_AddRemCommand ("menu_loadgame", M_Menu_Load_f); //q2...
Cmd_AddCommand ("menu_save", M_Menu_Save_f);
Cmd_AddCommand ("menu_load", M_Menu_Load_f);
Cmd_AddCommand ("menu_loadgame", M_Menu_Load_f); //q2...
#endif
Cmd_AddRemCommand ("menu_single", M_Menu_SinglePlayer_f);
Cmd_AddRemCommand ("menu_multi", M_Menu_MultiPlayer_f);
Cmd_AddRemCommand ("menu_demo", M_Menu_Demos_f);
Cmd_AddCommand ("menu_single", M_Menu_SinglePlayer_f);
Cmd_AddCommand ("menu_multi", M_Menu_MultiPlayer_f);
Cmd_AddCommand ("menu_demo", M_Menu_Demos_f);
Cmd_AddRemCommand ("menu_keys", M_Menu_Keys_f);
Cmd_AddRemCommand ("help", M_Menu_Help_f);
Cmd_AddRemCommand ("menu_quit", M_Menu_Quit_f);
Cmd_AddRemCommand ("menu_media", M_Menu_Media_f);
Cmd_AddRemCommand ("menu_mediafiles", M_Menu_MediaFiles_f);
Cmd_AddCommand ("menu_keys", M_Menu_Keys_f);
Cmd_AddCommand ("help", M_Menu_Help_f);
Cmd_AddCommand ("menu_quit", M_Menu_Quit_f);
Cmd_AddCommand ("menu_media", M_Menu_Media_f);
Cmd_AddCommand ("menu_mediafiles", M_Menu_MediaFiles_f);
#ifdef CL_MASTER
Cmd_AddRemCommand ("menu_servers", M_Menu_ServerList2_f);
Cmd_AddCommand ("menu_servers", M_Menu_ServerList2_f);
Cmd_AddRemCommand ("menu_slist", M_Menu_ServerList2_f);
Cmd_AddCommand ("menu_slist", M_Menu_ServerList2_f);
#endif
Cmd_AddRemCommand ("menu_setup", M_Menu_Setup_f);
Cmd_AddRemCommand ("menu_newmulti", M_Menu_GameOptions_f);
Cmd_AddCommand ("menu_setup", M_Menu_Setup_f);
Cmd_AddCommand ("menu_newmulti", M_Menu_GameOptions_f);
Cmd_AddRemCommand ("menu_main", M_Menu_Main_f); //I've moved main to last because that way tab give us main and not quit.
Cmd_AddCommand ("menu_main", M_Menu_Main_f); //I've moved main to last because that way tab give us main and not quit.
Cmd_AddRemCommand ("menu_options", M_Menu_Options_f);
Cmd_AddRemCommand ("menu_video", M_Menu_Video_f);
Cmd_AddRemCommand ("menu_audio", M_Menu_Audio_f);
Cmd_AddCommand ("menu_options", M_Menu_Options_f);
Cmd_AddCommand ("menu_video", M_Menu_Video_f);
Cmd_AddCommand ("menu_audio", M_Menu_Audio_f);
#ifndef __CYGWIN__
Cmd_AddRemCommand ("menu_speakers", M_Menu_Audio_Speakers_f);
Cmd_AddCommand ("menu_speakers", M_Menu_Audio_Speakers_f);
#endif
Cmd_AddRemCommand ("menu_spcheats", M_Menu_Singleplayer_Cheats_f);
Cmd_AddRemCommand ("menu_fps", M_Menu_FPS_f);
Cmd_AddRemCommand ("menu_render" , M_Menu_Render_f);
Cmd_AddRemCommand ("menu_lighting", M_Menu_Lighting_f);
Cmd_AddCommand ("menu_spcheats", M_Menu_Singleplayer_Cheats_f);
Cmd_AddCommand ("menu_fps", M_Menu_FPS_f);
Cmd_AddCommand ("menu_render" , M_Menu_Render_f);
Cmd_AddCommand ("menu_lighting", M_Menu_Lighting_f);
#ifdef GLQUAKE
Cmd_AddRemCommand ("menu_textures", M_Menu_Textures_f);
Cmd_AddCommand ("menu_textures", M_Menu_Textures_f);
#endif
Cmd_AddRemCommand ("menu_teamplay", M_Menu_Teamplay_f);
Cmd_AddRemCommand ("menu_teamplay_locations", M_Menu_Teamplay_Locations_f);
Cmd_AddRemCommand ("menu_teamplay_needs", M_Menu_Teamplay_Needs_f);
Cmd_AddRemCommand ("menu_teamplay_items", M_Menu_Teamplay_Items_f);
Cmd_AddRemCommand ("menu_teamplay_armor", M_Menu_Teamplay_Items_Armor_f);
Cmd_AddRemCommand ("menu_teamplay_weapons", M_Menu_Teamplay_Items_Weapons_f);
Cmd_AddRemCommand ("menu_teamplay_powerups", M_Menu_Teamplay_Items_Powerups_f);
Cmd_AddRemCommand ("menu_teamplay_ammo_health", M_Menu_Teamplay_Items_Ammo_Health_f);
Cmd_AddRemCommand ("menu_teamplay_team_fortress", M_Menu_Teamplay_Items_Team_Fortress_f);
Cmd_AddRemCommand ("menu_teamplay_status_location_misc", M_Menu_Teamplay_Items_Status_Location_Misc_f);
Cmd_AddRemCommand ("menu_particles", M_Menu_Particles_f);
Cmd_AddRemCommand ("menu_network", M_Menu_Network_f);
Cmd_AddCommand ("menu_teamplay", M_Menu_Teamplay_f);
Cmd_AddCommand ("menu_teamplay_locations", M_Menu_Teamplay_Locations_f);
Cmd_AddCommand ("menu_teamplay_needs", M_Menu_Teamplay_Needs_f);
Cmd_AddCommand ("menu_teamplay_items", M_Menu_Teamplay_Items_f);
Cmd_AddCommand ("menu_teamplay_armor", M_Menu_Teamplay_Items_Armor_f);
Cmd_AddCommand ("menu_teamplay_weapons", M_Menu_Teamplay_Items_Weapons_f);
Cmd_AddCommand ("menu_teamplay_powerups", M_Menu_Teamplay_Items_Powerups_f);
Cmd_AddCommand ("menu_teamplay_ammo_health", M_Menu_Teamplay_Items_Ammo_Health_f);
Cmd_AddCommand ("menu_teamplay_team_fortress", M_Menu_Teamplay_Items_Team_Fortress_f);
Cmd_AddCommand ("menu_teamplay_status_location_misc", M_Menu_Teamplay_Items_Status_Location_Misc_f);
Cmd_AddCommand ("menu_particles", M_Menu_Particles_f);
Cmd_AddCommand ("menu_network", M_Menu_Network_f);
#ifdef WEBCLIENT
Cmd_AddRemCommand ("menu_download", Menu_DownloadStuff_f);
Cmd_AddCommand ("menu_download", Menu_DownloadStuff_f);
#endif
#ifdef CL_MASTER
Cmd_AddRemCommand ("quickconnect", M_QuickConnect_f);
Cmd_AddCommand ("quickconnect", M_QuickConnect_f);
#endif
}

View file

@ -87,7 +87,6 @@ extern void (*R_RenderView) (void); // must set r_refdef first
extern void (*R_NewMap) (void);
extern void (*R_PreNewMap) (void);
extern int (*R_LightPoint) (vec3_t point);
extern void (*R_AddStain) (vec3_t org, float red, float green, float blue, float radius);
extern void (*R_LessenStains) (void);
@ -167,7 +166,7 @@ struct texid_s
union
{
unsigned int num;
#ifdef D3DQUAKE
#if defined(D3DQUAKE) || defined(SWQUAKE)
void *ptr;
#endif
};
@ -248,7 +247,6 @@ typedef struct rendererinfo_s {
void (*R_NewMap) (void);
void (*R_PreNewMap) (void);
int (*R_LightPoint) (vec3_t point);
void (*R_AddStain) (vec3_t org, float red, float green, float blue, float radius);
void (*R_LessenStains) (void);

View file

@ -2031,16 +2031,16 @@ static qboolean PScript_InitParticles (void)
memset(trailstates, 0, r_numtrailstates * sizeof(trailstate_t));
ts_cycle = 0;
Cmd_AddRemCommand("pointfile", P_ReadPointFile_f); //load the leak info produced from qbsp into the particle system to show a line. :)
Cmd_AddCommand("pointfile", P_ReadPointFile_f); //load the leak info produced from qbsp into the particle system to show a line. :)
Cmd_AddRemCommand("r_part", P_ParticleEffect_f);
Cmd_AddCommand("r_part", P_ParticleEffect_f);
Cmd_AddRemCommand("r_exportbuiltinparticles", P_ExportBuiltinSet_f);
Cmd_AddRemCommand("r_importeffectinfo", P_ImportEffectInfo_f);
Cmd_AddCommand("r_exportbuiltinparticles", P_ExportBuiltinSet_f);
Cmd_AddCommand("r_importeffectinfo", P_ImportEffectInfo_f);
#if _DEBUG
Cmd_AddRemCommand("r_partinfo", P_PartInfo_f);
Cmd_AddRemCommand("r_beaminfo", P_BeamInfo_f);
Cmd_AddCommand("r_partinfo", P_PartInfo_f);
Cmd_AddCommand("r_beaminfo", P_BeamInfo_f);
#endif

View file

@ -120,6 +120,7 @@ extern sfx_t *cl_sfx_r_exp3;
/*These are pointers to the csqc's globals.*/ \
globalfloat(svtime, "time"); /*float Written before entering most qc functions*/ \
globalfloat(frametime, "frametime"); /*float Written before entering most qc functions*/ \
globalfloat(gamespeed, "gamespeed"); /*float Written before entering most qc functions*/ \
globalfloat(cltime, "cltime"); /*float Written before entering most qc functions*/ \
globalfloat(physics_mode, "physics_mode"); /*float Written before entering most qc functions*/ \
globalentity(self, "self"); /*entity Written before entering most qc functions*/ \
@ -1622,20 +1623,19 @@ static void QCBUILTIN PF_cs_tracetoss (progfuncs_t *prinst, struct globalvars_s
cs_settracevars(&trace);
}
static int CS_PointContents(vec3_t org)
{
if (!cl.worldmodel)
return FTECONTENTS_EMPTY;
return cl.worldmodel->funcs.PointContents(cl.worldmodel, NULL, org);
}
static void QCBUILTIN PF_cs_pointcontents(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
world_t *w = prinst->parms->user;
float *v;
int cont;
v = G_VECTOR(OFS_PARM0);
cont = CS_PointContents(v);
if (!cl.worldmodel)
return FTECONTENTS_EMPTY;
cont = World_PointContents(w, v);
if (cont & FTECONTENTS_SOLID)
G_FLOAT(OFS_RETURN) = Q1CONTENTS_SOLID;
else if (cont & FTECONTENTS_SKY)
@ -2080,6 +2080,11 @@ static void QCBUILTIN PF_cs_getinputstate (progfuncs_t *prinst, struct globalvar
extern usercmd_t independantphysics[MAX_SPLITS];
f = G_FLOAT(OFS_PARM0);
if (cl.paused && f >= cls.netchan.incoming_sequence)
{
G_FLOAT(OFS_RETURN) = false;
return;
}
if (f > cls.netchan.outgoing_sequence)
{
G_FLOAT(OFS_RETURN) = false;
@ -2090,8 +2095,6 @@ static void QCBUILTIN PF_cs_getinputstate (progfuncs_t *prinst, struct globalvar
G_FLOAT(OFS_RETURN) = false;
return;
}
if (cl.paused)
f = cls.netchan.outgoing_sequence;
/*outgoing_sequence says how many packets have actually been sent, but there's an extra pending packet which has not been sent yet - be warned though, its data will change in the coming frames*/
if (f == cls.netchan.outgoing_sequence)
@ -3460,7 +3463,7 @@ static void QCBUILTIN PF_cs_registercommand (progfuncs_t *prinst, struct globalv
if (!strcmp(str, "+showscores") || !strcmp(str, "-showscores") ||
!strcmp(str, "+showteamscores") || !strcmp(str, "-showteamscores"))
return;
Cmd_AddRemCommand(str, CS_ConsoleCommand_f);
Cmd_AddCommand(str, CS_ConsoleCommand_f);
}
static qboolean csqc_usinglistener;
@ -3499,7 +3502,7 @@ static void CSQC_LerpStateToCSQC(lerpents_t *le, csqcedict_t *ent, qboolean nole
ent->xv->lerpfrac = bound(0, cl.servertime - le->newframestarttime, 0.1);
/* if (nolerp)
if (nolerp)
{
ent->v->origin[0] = le->neworigin[0];
ent->v->origin[1] = le->neworigin[1];
@ -3508,7 +3511,7 @@ static void CSQC_LerpStateToCSQC(lerpents_t *le, csqcedict_t *ent, qboolean nole
ent->v->angles[1] = le->newangle[1];
ent->v->angles[2] = le->newangle[2];
}
else*/
else
{
ent->v->origin[0] = le->origin[0];
ent->v->origin[1] = le->origin[1];
@ -5324,8 +5327,6 @@ void CSQC_Breakpoint_f(void)
static void CSQC_GameCommand_f(void);
void CSQC_RegisterCvarsAndThings(void)
{
PF_Common_RegisterCvars();
Cmd_AddCommand("coredump_csqc", CSQC_CoreDump);
Cmd_AddCommand ("extensionlist_csqc", PR_CSExtensionList_f);
Cmd_AddCommand("cl_cmd", CSQC_GameCommand_f);
@ -5401,6 +5402,17 @@ qboolean CSQC_DrawView(void)
*csqcg.clientcommandframe = cls.netchan.outgoing_sequence;
if (csqcg.servercommandframe)
*csqcg.servercommandframe = cl.ackedinputsequence;
if (csqcg.gamespeed)
*csqcg.gamespeed = cl.gamespeed;
}
else
{
if (csqcg.clientcommandframe)
*csqcg.clientcommandframe = cl.ackedinputsequence;
if (csqcg.servercommandframe)
*csqcg.servercommandframe = cl.ackedinputsequence;
if (csqcg.gamespeed)
*csqcg.gamespeed = 0;
}
if (csqcg.intermission)
*csqcg.intermission = cl.intermission;

View file

@ -1933,8 +1933,6 @@ void MP_Reload_f(void)
void MP_RegisterCvarsAndCmds(void)
{
PF_Common_RegisterCvars();
Cmd_AddCommand("coredump_menuqc", MP_CoreDump_f);
Cmd_AddCommand("menu_restart", MP_Reload_f);

View file

@ -1340,6 +1340,7 @@ dynamic:
=============================================================
*/
#if 0
static qbyte *R_MarkLeafSurfaces_Q1 (void)
{
qbyte *vis;
@ -1397,6 +1398,7 @@ static qbyte *R_MarkLeafSurfaces_Q1 (void)
}
return vis;
}
#endif
/*
================
@ -1613,6 +1615,7 @@ static void Surf_RecursiveQ2WorldNode (mnode_t *node)
#endif
#ifdef Q3BSPS
#if 0
static void Surf_LeafWorldNode (void)
{
int i;
@ -1678,7 +1681,6 @@ static void Surf_LeafWorldNode (void)
{
int j;
texture_t *tex;
@ -1699,6 +1701,7 @@ static void Surf_LeafWorldNode (void)
}
}
}
#endif
static void Surf_RecursiveQ3WorldNode (mnode_t *node, unsigned int clipflags)
{
@ -1945,7 +1948,7 @@ void Surf_SetupFrame(void)
V_SetContentsColor (r_viewcontents);
}
/*
static mesh_t *surfbatchmeshes[256];
static void Surf_BuildBrushBatch(batch_t *batch)
{
@ -1958,11 +1961,13 @@ static void Surf_BuildBrushBatch(batch_t *batch)
surfbatchmeshes[i] = model->surfaces[batch->surf_first + i].mesh;
}
}
*/
void Surf_GenBrushBatches(batch_t **batches, entity_t *ent)
{
int i;
msurface_t *s;
batch_t *ob;
model_t *model;
batch_t *b;
unsigned int bef;
@ -2036,77 +2041,32 @@ void Surf_GenBrushBatches(batch_t **batches, entity_t *ent)
if (ent->flags & RF_NOSHADOW)
bef |= BEF_NOSHADOWS;
if (!model->surfaces && model->batches)
for (i = 0; i < SHADER_SORT_COUNT; i++)
for (ob = model->batches[i]; ob; ob = ob->next)
{
for (i = 0; i < model->numsurfaces; i++)
b = BE_GetTempBatch();
if (!b)
continue;
*b = *ob;
b->shader = R_TextureAnimation(ent->framestate.g[FS_REG].frame[0], b->texture)->shader;
b->meshes = b->maxmeshes;
b->ent = ent;
if (bef & BEF_FORCEADDITIVE)
{
b = BE_GetTempBatch();
if (!b)
continue;
*b = model->batches[0][i];
b->mesh = (mesh_t**)&model->batches[0][i].mesh;
b->ent = ent;
if (bef & BEF_FORCEADDITIVE)
{
b->next = batches[SHADER_SORT_ADDITIVE];
batches[SHADER_SORT_ADDITIVE] = b;
}
else if (bef & BEF_FORCETRANSPARENT)
{
b->next = batches[SHADER_SORT_BLEND];
batches[SHADER_SORT_BLEND] = b;
}
else
{
b->next = batches[b->shader->sort];
batches[b->shader->sort] = b;
}
b->next = batches[SHADER_SORT_ADDITIVE];
batches[SHADER_SORT_ADDITIVE] = b;
}
return;
}
b = NULL;
for (s = model->surfaces+model->firstmodelsurface,i = 0; i < model->nummodelsurfaces; i++, s++)
{
if (!b || b->lightmap != s->lightmaptexturenum || b->texture != s->texinfo->texture || b->surf_count >= sizeof(surfbatchmeshes)/sizeof(surfbatchmeshes[0]))
else if (bef & BEF_FORCETRANSPARENT)
{
b = BE_GetTempBatch();
if (!b)
break;
b->buildmeshes = NULL;
b->ent = ent;
b->texture = s->texinfo->texture;
b->shader = R_TextureAnimation(ent->framestate.g[FS_REG].frame[0], b->texture)->shader;
b->skin = &b->shader->defaulttextures;
b->flags = bef;
if (bef & BEF_FORCEADDITIVE)
{
b->next = batches[SHADER_SORT_ADDITIVE];
batches[SHADER_SORT_ADDITIVE] = b;
}
else if (bef & BEF_FORCETRANSPARENT)
{
b->next = batches[SHADER_SORT_BLEND];
batches[SHADER_SORT_BLEND] = b;
}
else
{
b->next = batches[b->shader->sort];
batches[b->shader->sort] = b;
}
b->surf_first = s - model->surfaces;
b->surf_count = 0;
b->buildmeshes = Surf_BuildBrushBatch;
b->meshes = 0;
b->firstmesh = 0;
b->lightmap = s->lightmaptexturenum;
b->mesh = NULL;
b->vbo = &b->texture->vbo;
b->next = batches[SHADER_SORT_BLEND];
batches[SHADER_SORT_BLEND] = b;
}
else
{
b->next = batches[b->shader->sort];
batches[b->shader->sort] = b;
}
b->surf_count++;
b->meshes++;
}
}
@ -2199,9 +2159,9 @@ void Surf_DrawWorld (void)
#endif
{
//extern cvar_t temp1;
if (0)//temp1.value)
vis = R_MarkLeafSurfaces_Q1();
else
// if (0)//temp1.value)
// vis = R_MarkLeafSurfaces_Q1();
// else
{
vis = R_MarkLeaves_Q1 ();
if (!(r_novis.ival & 2))
@ -2431,6 +2391,20 @@ static int Surf_LM_FillBlock (int texnum, int w, int h, int x, int y)
return texnum;
}
unsigned int Surf_CalcMemSize(msurface_t *surf)
{
if (surf->mesh)
return 0;
if (!surf->numedges)
return 0;
//figure out how much space this surface needs
return sizeof(mesh_t) +
sizeof(index_t)*(surf->numedges-2)*3 +
(sizeof(vecV_t)+sizeof(vec2_t)*2+sizeof(vec3_t)*3+sizeof(vec4_t))*surf->numedges;
}
/*
================
BuildSurfaceDisplayList
@ -2438,13 +2412,14 @@ FIXME: this is probably misplaced
lightmaps are already built by the time this is called
================
*/
void Surf_BuildSurfaceDisplayList (model_t *model, msurface_t *fa)
void Surf_BuildSurfaceDisplayList (model_t *model, msurface_t *fa, void **mem)
{
int i, lindex, lnumverts;
medge_t *pedges, *r_pedge;
int vertpage;
float *vec;
float s, t;
float s, t, d;
mesh_t *mesh;
// reconstruct the polygon
pedges = model->edges;
@ -2457,80 +2432,80 @@ void Surf_BuildSurfaceDisplayList (model_t *model, msurface_t *fa)
return;
}
{ //build a nice mesh instead of a poly.
int size = sizeof(mesh_t) + sizeof(index_t)*(lnumverts-2)*3 + (sizeof(vecV_t) + 3*sizeof(vec3_t) + 2*sizeof(vec2_t) + sizeof(vec4_t))*lnumverts;
mesh_t *mesh;
fa->mesh = mesh = *mem;
mesh->xyz_array = (vecV_t*)(mesh + 1);
mesh->normals_array = (vec3_t*)(mesh->xyz_array + lnumverts);
mesh->snormals_array = (vec3_t*)(mesh->normals_array + lnumverts);
mesh->tnormals_array = (vec3_t*)(mesh->snormals_array + lnumverts);
mesh->st_array = (vec2_t*)(mesh->tnormals_array + lnumverts);
mesh->lmst_array = (vec2_t*)(mesh->st_array + lnumverts);
mesh->colors4f_array = (vec4_t*)(mesh->lmst_array + lnumverts);
mesh->indexes = (index_t*)(mesh->colors4f_array + lnumverts);
*mem = (void*)(mesh->indexes + (lnumverts-2)*3);
fa->mesh = mesh = Hunk_Alloc(size);
mesh->xyz_array = (vecV_t*)(mesh + 1);
mesh->normals_array = (vec3_t*)(mesh->xyz_array + lnumverts);
mesh->snormals_array = (vec3_t*)(mesh->normals_array + lnumverts);
mesh->tnormals_array = (vec3_t*)(mesh->snormals_array + lnumverts);
mesh->st_array = (vec2_t*)(mesh->tnormals_array + lnumverts);
mesh->lmst_array = (vec2_t*)(mesh->st_array + lnumverts);
mesh->colors4f_array = (vec4_t*)(mesh->lmst_array + lnumverts);
mesh->indexes = (index_t*)(mesh->colors4f_array + lnumverts);
mesh->numindexes = (lnumverts-2)*3;
mesh->numvertexes = lnumverts;
mesh->istrifan = true;
mesh->numindexes = (lnumverts-2)*3;
mesh->numvertexes = lnumverts;
mesh->istrifan = true;
for (i=0 ; i<lnumverts-2 ; i++)
{
mesh->indexes[i*3] = 0;
mesh->indexes[i*3+1] = i+1;
mesh->indexes[i*3+2] = i+2;
}
for (i=0 ; i<lnumverts-2 ; i++)
for (i=0 ; i<lnumverts ; i++)
{
lindex = model->surfedges[fa->firstedge + i];
if (lindex > 0)
{
mesh->indexes[i*3] = 0;
mesh->indexes[i*3+1] = i+1;
mesh->indexes[i*3+2] = i+2;
r_pedge = &pedges[lindex];
vec = model->vertexes[r_pedge->v[0]].position;
}
else
{
r_pedge = &pedges[-lindex];
vec = model->vertexes[r_pedge->v[1]].position;
}
for (i=0 ; i<lnumverts ; i++)
{
lindex = model->surfedges[fa->firstedge + i];
s = DotProduct (vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3];
t = DotProduct (vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3];
if (lindex > 0)
{
r_pedge = &pedges[lindex];
vec = model->vertexes[r_pedge->v[0]].position;
}
else
{
r_pedge = &pedges[-lindex];
vec = model->vertexes[r_pedge->v[1]].position;
}
VectorCopy (vec, mesh->xyz_array[i]);
mesh->st_array[i][0] = s/fa->texinfo->texture->width;
mesh->st_array[i][1] = t/fa->texinfo->texture->height;
s = DotProduct (vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3];
t = DotProduct (vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3];
s -= fa->texturemins[0];
s += fa->light_s*16;
s += 8;
s /= LMBLOCK_WIDTH*16;
VectorCopy (vec, mesh->xyz_array[i]);
mesh->st_array[i][0] = s/fa->texinfo->texture->width;
mesh->st_array[i][1] = t/fa->texinfo->texture->height;
t -= fa->texturemins[1];
t += fa->light_t*16;
t += 8;
t /= LMBLOCK_HEIGHT*16;
s -= fa->texturemins[0];
s += fa->light_s*16;
s += 8;
s /= LMBLOCK_WIDTH*16;
mesh->lmst_array[i][0] = s;
mesh->lmst_array[i][1] = t;
t -= fa->texturemins[1];
t += fa->light_t*16;
t += 8;
t /= LMBLOCK_HEIGHT*16;
if (fa->flags & SURF_PLANEBACK)
VectorNegate(fa->plane->normal, mesh->normals_array[i]);
else
VectorCopy(fa->plane->normal, mesh->normals_array[i]);
VectorNegate(fa->texinfo->vecs[0], mesh->snormals_array[i]);
VectorNegate(fa->texinfo->vecs[1], mesh->tnormals_array[i]);
d = -DotProduct(mesh->normals_array[i], mesh->snormals_array[i]);
VectorMA(mesh->snormals_array[i], d, mesh->normals_array[i], mesh->snormals_array[i]);
d = -DotProduct(mesh->normals_array[i], mesh->tnormals_array[i]);
VectorMA(mesh->tnormals_array[i], d, mesh->normals_array[i], mesh->tnormals_array[i]);
VectorNormalize(mesh->snormals_array[i]);
VectorNormalize(mesh->tnormals_array[i]);
mesh->lmst_array[i][0] = s;
mesh->lmst_array[i][1] = t;
if (fa->flags & SURF_PLANEBACK)
VectorNegate(fa->plane->normal, mesh->normals_array[i]);
else
VectorCopy(fa->plane->normal, mesh->normals_array[i]);
VectorNegate(fa->texinfo->vecs[0], mesh->snormals_array[i]);
VectorNegate(fa->texinfo->vecs[1], mesh->tnormals_array[i]);
VectorNormalize(mesh->snormals_array[i]);
VectorNormalize(mesh->tnormals_array[i]);
mesh->colors4f_array[i][0] = 1;
mesh->colors4f_array[i][1] = 1;
mesh->colors4f_array[i][2] = 1;
mesh->colors4f_array[i][3] = 1;
}
mesh->colors4f_array[i][0] = 1;
mesh->colors4f_array[i][1] = 1;
mesh->colors4f_array[i][2] = 1;
mesh->colors4f_array[i][3] = 1;
}
}
@ -2627,6 +2602,7 @@ void Surf_DeInit(void)
void Surf_Clear(model_t *mod)
{
batch_t *b;
vbo_t *vbo;
int i;
if (mod->fromgame == fg_doom3)
return;/*they're on the hunk*/
@ -2640,41 +2616,22 @@ void Surf_Clear(model_t *mod)
Z_Free(b);
}
}
}
/*
==================
GL_BuildLightmaps
Builds the lightmap texture
with all the surfaces from all brush models
Groups surfaces into their respective batches (based on the lightmap number).
==================
*/
void Surf_BuildLightmaps (void)
{
int i, j, t;
model_t *m;
int shift;
msurface_t *surf;
batch_t *batch, *bstop;
vec3_t sn;
int sortid;
int ptype;
r_framecount = 1; // no dlightcache
for (i = 0; i < numlightmaps; i++)
while(mod->vbos)
{
if (!lightmap[i])
break;
BZ_Free(lightmap[i]);
lightmap[i] = NULL;
vbo = mod->vbos;
mod->vbos = vbo->next;
BE_ClearVBO(vbo);
}
if (cl.worldmodel->fromgame == fg_doom)
return; //no lightmaps.
BZ_Free(mod->shadowbatches);
mod->numshadowbatches = 0;
mod->shadowbatches = NULL;
Sh_PurgeShadowMeshes();
}
//pick fastest mode for lightmap data
void Surf_LightmapMode(void)
{
lightmap_bgra = true;
switch(qrenderer)
@ -2713,82 +2670,141 @@ void Surf_BuildLightmaps (void)
case QR_NONE:
break;
}
}
/*
==================
GL_BuildLightmaps
Builds the lightmap texture
with all the surfaces from all brush models
Groups surfaces into their respective batches (based on the lightmap number).
==================
*/
void Surf_BuildLightmaps (void)
{
int i, j, t;
model_t *m;
int shift;
msurface_t *surf;
batch_t *batch, *bstop;
vec3_t sn;
int sortid;
int ptype;
void *mem;
unsigned int memsize;
r_framecount = 1; // no dlightcache
for (i = 0; i < numlightmaps; i++)
{
if (!lightmap[i])
break;
BZ_Free(lightmap[i]);
lightmap[i] = NULL;
}
Surf_LightmapMode();
if (cl.worldmodel->fromgame == fg_doom)
return; //no lightmaps.
for (j=1 ; j<MAX_MODELS ; j++)
{
m = cl.model_precache[j];
if (!m)
break;
if (m->name[0] == '*')
if (m->type != mod_brush)
continue;
currentmodel = m;
shift = Surf_LightmapShift(currentmodel);
memsize = 0;
for (i=0; i<m->nummodelsurfaces; i++)
{
surf = m->surfaces + i + m->firstmodelsurface;
memsize += Surf_CalcMemSize(surf);
}
mem = Hunk_AllocName(memsize, m->name);
for (i=0; i<m->nummodelsurfaces; i++)
{
surf = m->surfaces + i + m->firstmodelsurface;
if (surf->mesh) //there are some surfaces that have a display list already (q3 ones)
continue;
Surf_CreateSurfaceLightmap (surf, shift);
Surf_BuildSurfaceDisplayList (m, surf, &mem);
}
for (t = m->numtextures-1; t >= 0; t--)
{
if (m == cl.worldmodel)
ptype = P_FindParticleType(va("tex_%s", m->textures[t]->name));
else
ptype = P_INVALID;
m->textures[t]->wtexno = t;
sortid = m->textures[t]->shader->sort;
bstop = m->batches[sortid];
batch = NULL;
for (i=0 ; i<m->numsurfaces ; i++)
for (i=0; i<m->nummodelsurfaces; i++)
{//extra texture loop so we get slightly less texture switches
surf = m->surfaces + i;
surf = m->surfaces + i + m->firstmodelsurface;
if (surf->texinfo->texture == m->textures[t])
{
P_EmitSkyEffectTris(m, surf, ptype);
Surf_CreateSurfaceLightmap (surf, shift);
/*the excessive logic is to give portals separate batches for separate planes*/
if (sortid == SHADER_SORT_PORTAL)
if (sortid == SHADER_SORT_PORTAL || (m->textures[t]->shader->flags & (SHADER_HASREFLECT | SHADER_HASREFRACT)))
{
if (surf->flags & SURF_PLANEBACK)
VectorNegate(surf->plane->normal, sn);
else
VectorCopy(surf->plane->normal, sn);
if (!batch || batch->lightmap != surf->lightmaptexturenum || batch->firstmesh + surf->mesh->numvertexes > MAX_INDICIES || !VectorCompare(sn, batch->normal))
{
for (batch = m->batches[sortid]; batch != bstop; batch = batch->next)
{
if (batch->lightmap == surf->lightmaptexturenum && VectorCompare(sn, batch->normal) && batch->firstmesh + surf->mesh->numvertexes <= MAX_INDICIES)
break;
}
if (batch == bstop)
{
batch = Z_Malloc(sizeof(*batch));
batch->lightmap = surf->lightmaptexturenum;
batch->texture = m->textures[t];
batch->next = m->batches[sortid];
batch->ent = &r_worldentity;
VectorCopy(sn, batch->normal);
m->batches[sortid] = batch;
}
}
}
else
VectorClear(sn);
if (!batch || batch->lightmap != surf->lightmaptexturenum || (sortid == SHADER_SORT_PORTAL && !VectorCompare(sn, batch->normal)))
{
if (sortid == SHADER_SORT_PORTAL)
if (!batch || batch->lightmap != surf->lightmaptexturenum || batch->firstmesh + surf->mesh->numvertexes > MAX_INDICIES)
{
for (batch = m->batches[sortid]; batch != bstop; batch = batch->next)
{
if (batch->lightmap == surf->lightmaptexturenum && VectorCompare(sn, batch->normal))
if (batch->lightmap == surf->lightmaptexturenum && batch->firstmesh + surf->mesh->numvertexes <= MAX_INDICIES)
break;
}
}
else
{
for (batch = m->batches[sortid]; batch != bstop; batch = batch->next)
if (batch == bstop)
{
if (batch->lightmap == surf->lightmaptexturenum)
break;
batch = Z_Malloc(sizeof(*batch));
batch->lightmap = surf->lightmaptexturenum;
batch->texture = m->textures[t];
batch->next = m->batches[sortid];
batch->ent = &r_worldentity;
VectorClear(batch->normal);
m->batches[sortid] = batch;
}
}
if (batch == bstop)
{
batch = Z_Malloc(sizeof(*batch));
batch->lightmap = surf->lightmaptexturenum;
batch->texture = m->textures[t];
batch->next = m->batches[sortid];
batch->ent = &r_worldentity;
VectorCopy(sn, batch->normal);
m->batches[sortid] = batch;
}
}
surf->sbatch = batch;
batch->maxmeshes++;
if (m->surfaces[i].mesh) //there are some surfaces that have a display list already (q3 ones)
continue;
Surf_BuildSurfaceDisplayList (m, surf);
batch->firstmesh += surf->mesh->numvertexes;
}
}
}
@ -2797,12 +2813,24 @@ void Surf_BuildLightmaps (void)
{
batch->mesh = BZ_Malloc(sizeof(*batch->mesh)*batch->maxmeshes*2);
}
for (i=0; i<m->nummodelsurfaces; i++)
{
surf = m->surfaces + i + m->firstmodelsurface;
surf->sbatch->mesh[surf->sbatch->meshes++] = surf->mesh;
}
BE_GenBrushModelVBO(m);
for (sortid = 0; sortid < SHADER_SORT_COUNT; sortid++)
/*for (sortid = 0; sortid < SHADER_SORT_COUNT; sortid++)
for (batch = m->batches[sortid]; batch != NULL; batch = batch->next)
{
batch->vbo = &batch->texture->vbo;
}
*/
for (sortid = 0; sortid < SHADER_SORT_COUNT; sortid++)
for (batch = m->batches[sortid]; batch != NULL; batch = batch->next)
{
batch->firstmesh = 0;
batch->meshes = 0;
}
}
BE_UploadAllLightmaps();

View file

@ -197,7 +197,6 @@ void Surf_WipeStains(void);
void Surf_DeInit(void);
void Surf_Clear(struct model_s *mod);
void Surf_BuildLightmaps(void);
void Surf_BuildSurfaceDisplayList (struct model_s *mod, struct msurface_s *fa);
void Surf_RenderDynamicLightmaps (struct msurface_s *fa);
void Surf_RenderAmbientLightmaps (struct msurface_s *fa, int ambient);
int Surf_LightmapShift (struct model_s *model);
@ -249,17 +248,13 @@ void GLR_NewMap (void);
void GLR_PushDlights (void);
void GLR_DrawWaterSurfaces (void);
void MediaGL_ShowFrame8bit(qbyte *framedata, int inwidth, int inheight, qbyte *palette);
void MediaGL_ShowFrameRGBA_32(qbyte *framedata, int inwidth, int inheight); //top down
void MediaGL_ShowFrameBGR_24_Flip(qbyte *framedata, int inwidth, int inheight); //input is bottom up...
void GLVID_DeInit (void);
void GLR_DeInit (void);
void GLSCR_DeInit (void);
void GLVID_Console_Resize(void);
int GLR_LightPoint (vec3_t p);
#endif
int R_LightPoint (vec3_t p);
void R_RenderDlights (void);
enum imageflags
{

View file

@ -126,6 +126,7 @@ cvar_t r_stainfadetime = SCVAR ("r_stainfadetime", "1");
cvar_t r_stains = CVARFC("r_stains", IFMINIMAL("0","0.75"),
CVAR_ARCHIVE,
Cvar_Limiter_ZeroToOne_Callback);
cvar_t r_postprocshader = CVARD("r_postprocshader", "", "Specifies a shader to use as a post-processing shader");
cvar_t r_wallcolour = CVARAF ("r_wallcolour", "128 128 128",
"r_wallcolor", CVAR_RENDERERCALLBACK|CVAR_SHADERSYSTEM);//FIXME: broken
cvar_t r_walltexture = CVARF ("r_walltexture", "",
@ -323,6 +324,8 @@ cvar_t r_shadow_realtime_world_shadows = SCVARF ("r_shadow_realtime_world_shado
cvar_t r_shadow_realtime_dlight = SCVARF ("r_shadow_realtime_dlight", "1", CVAR_ARCHIVE);
cvar_t r_shadow_realtime_dlight_shadows = SCVARF ("r_shadow_realtime_dlight_shadows", "1", CVAR_ARCHIVE);
cvar_t r_shadow_realtime_world_lightmaps = SCVARF ("r_shadow_realtime_world_lightmaps", "0", 0);
cvar_t r_sun_dir = SCVAR ("r_sun_dir", "0.2 0.5 0.8");
cvar_t r_sun_colour = SCVARF ("r_sun_colour", "0 0 0", CVAR_ARCHIVE);
cvar_t r_vertexdlights = SCVAR ("r_vertexdlights", "0");
@ -374,6 +377,7 @@ void GLRenderer_Init(void)
Cvar_Register (&gl_finish, GLRENDEREROPTIONS);
Cvar_Register (&gl_lateswap, GLRENDEREROPTIONS);
Cvar_Register (&gl_lerpimages, GLRENDEREROPTIONS);
Cvar_Register (&r_postprocshader, GLRENDEREROPTIONS);
Cvar_Register (&dpcompat_psa_ungroup, GLRENDEREROPTIONS);
Cvar_Register (&r_noportals, GLRENDEREROPTIONS);
@ -412,7 +416,6 @@ void GLRenderer_Init(void)
Cvar_Register (&gl_texture_anisotropic_filtering, GLRENDEREROPTIONS);
Cvar_Register (&gl_savecompressedtex, GLRENDEREROPTIONS);
Cvar_Register (&gl_compress, GLRENDEREROPTIONS);
Cvar_Register (&gl_driver, GLRENDEREROPTIONS);
Cvar_Register (&gl_detail, GRAPHICALNICETIES);
Cvar_Register (&gl_detailscale, GRAPHICALNICETIES);
Cvar_Register (&gl_overbright, GRAPHICALNICETIES);
@ -438,7 +441,6 @@ void GLRenderer_Init(void)
Cvar_Register (&gl_schematics, GLRENDEREROPTIONS);
Cvar_Register (&r_vertexlight, GLRENDEREROPTIONS);
Cvar_Register (&gl_shadeq1_name, GLRENDEREROPTIONS);
Cvar_Register (&gl_blend2d, GLRENDEREROPTIONS);
@ -458,7 +460,6 @@ void R_InitTextures (void)
// create a simple checkerboard texture for the default
r_notexture_mip = Z_Malloc (sizeof(texture_t) + 16*16+8*8+4*4+2*2);
r_notexture_mip->pixbytes = 1;
r_notexture_mip->width = r_notexture_mip->height = 16;
r_notexture_mip->offsets[0] = sizeof(texture_t);
r_notexture_mip->offsets[1] = r_notexture_mip->offsets[0] + 16*16;
@ -512,11 +513,21 @@ void Renderer_Init(void)
GLRenderer_Init();
#endif
#ifdef SWQUAKE
{
extern cvar_t sw_interlace;
extern cvar_t sw_threads;
Cvar_Register(&sw_interlace, "Software Rendering Options");
Cvar_Register(&sw_threads, "Software Rendering Options");
}
#endif
Cvar_Register (&gl_conback, GRAPHICALNICETIES);
Cvar_Register (&r_novis, GLRENDEREROPTIONS);
//but register ALL vid_ commands.
Cvar_Register (&gl_driver, GLRENDEREROPTIONS);
Cvar_Register (&_vid_wait_override, VIDCOMMANDGROUP);
Cvar_Register (&_windowed_mouse, VIDCOMMANDGROUP);
Cvar_Register (&vid_renderer, VIDCOMMANDGROUP);
@ -563,7 +574,8 @@ void Renderer_Init(void)
Cvar_Register (&r_shadow_realtime_dlight, GRAPHICALNICETIES);
Cvar_Register (&r_shadow_realtime_dlight_shadows, GRAPHICALNICETIES);
Cvar_Register (&r_shadow_realtime_world_lightmaps, GRAPHICALNICETIES);
Cvar_Register (&r_sun_dir, GRAPHICALNICETIES);
Cvar_Register (&r_sun_colour, GRAPHICALNICETIES);
Cvar_Register(&scr_viewsize, SCREENOPTIONS);
Cvar_Register(&scr_fov, SCREENOPTIONS);
@ -616,6 +628,7 @@ void Renderer_Init(void)
Cvar_Register (&r_fastsky, GRAPHICALNICETIES);
Cvar_Register (&r_fastskycolour, GRAPHICALNICETIES);
Cvar_Register (&r_wateralpha, GRAPHICALNICETIES);
Cvar_Register (&gl_shadeq1_name, GLRENDEREROPTIONS);
Cvar_Register (&r_clear, GLRENDEREROPTIONS);
Cvar_Register (&gl_max_size, GLRENDEREROPTIONS);
@ -683,7 +696,6 @@ void (*R_RenderView) (void); // must set r_refdef first
void (*R_NewMap) (void);
void (*R_PreNewMap) (void);
int (*R_LightPoint) (vec3_t point);
void (*R_AddStain) (vec3_t org, float red, float green, float blue, float radius);
void (*R_LessenStains) (void);
@ -747,7 +759,6 @@ rendererinfo_t dedicatedrendererinfo = {
NULL, //R_NewMap;
NULL, //R_PreNewMap
NULL, //R_LightPoint;
NULL, //R_AddStain;
@ -806,9 +817,9 @@ rendererinfo_t dedicatedrendererinfo = {
rendererinfo_t *pdedicatedrendererinfo = &dedicatedrendererinfo;
rendererinfo_t openglrendererinfo;
rendererinfo_t d3dfglrendererinfo;
rendererinfo_t d3drendererinfo;
rendererinfo_t swrendererinfo;
rendererinfo_t *rendererinfo[] =
{
@ -817,11 +828,13 @@ rendererinfo_t *rendererinfo[] =
#endif
#ifdef GLQUAKE
&openglrendererinfo,
&d3dfglrendererinfo,
#endif
#ifdef D3DQUAKE
&d3drendererinfo,
#endif
#ifdef SWQUAKE
&swrendererinfo,
#endif
};
@ -842,7 +855,6 @@ void R_SetRenderer(rendererinfo_t *ri)
R_RenderView = ri->R_RenderView;
R_NewMap = ri->R_NewMap;
R_PreNewMap = ri->R_PreNewMap;
R_LightPoint = ri->R_LightPoint;
R_AddStain = ri->R_AddStain;
R_LessenStains = ri->R_LessenStains;
@ -928,6 +940,22 @@ void R_ShutdownRenderer(void)
S_Shutdown();
}
void R_GenPaletteLookup(void)
{
int r,g,b,i;
unsigned char *pal = host_basepal;
for (i=0 ; i<256 ; i++)
{
r = pal[0];
g = pal[1];
b = pal[2];
pal += 3;
d_8to24rgbtable[i] = (255<<24) + (r<<0) + (g<<8) + (b<<16);
}
d_8to24rgbtable[255] &= 0xffffff; // 255 is transparent
}
qboolean R_ApplyRenderer (rendererstate_t *newr)
{
if (newr->bpp == -1)
@ -970,7 +998,7 @@ qboolean R_ApplyRenderer_Load (rendererstate_t *newr)
isDedicated = false;
#endif
if (newr)
Con_Printf("Setting mode %i*%i*%i*%i\n", newr->width, newr->height, newr->bpp, newr->rate);
Con_Printf("Setting mode %i*%i*%i*%i %s\n", newr->width, newr->height, newr->bpp, newr->rate, newr->renderer->description);
if (host_basepal)
BZ_Free(host_basepal);
@ -1015,6 +1043,8 @@ qboolean R_ApplyRenderer_Load (rendererstate_t *newr)
BZ_Free(colormap);
}
R_GenPaletteLookup();
if (h2playertranslations)
BZ_Free(h2playertranslations);
h2playertranslations = FS_LoadMallocFile ("gfx/player.lmp");
@ -2095,6 +2125,9 @@ void R_SetFrustum (float projmat[16], float viewmat[16])
frustum[i].signbits = SignbitsForPlane (&frustum[i]);
}
if (r_refdef.recurse)
return;
#if FRUSTUMPLANES > 4
//do far plane
//fog will not logically not actually reach 0, though precision issues will force it. we cut off at an exponant of -500

View file

@ -94,6 +94,7 @@ enum
};
int SCR_GetLoadingStage(void);
void SCR_SetLoadingStage(int stage);
void SCR_SetLoadingFile(char *str);
/*fonts*/

View file

@ -1189,6 +1189,8 @@ void S_Shutdown(void)
sound_started = 0;
S_Purge(false);
num_sfx = 0;
}
@ -1258,10 +1260,8 @@ void S_Purge(qboolean retaintouched)
/*if there's any data associated still, kill it. if present, it should be a single sfxcache_t (with data in same alloc)*/
if (sfx->decoder.buf)
{
BZ_Free(sfx->decoder.buf);
sfx->decoder.buf = NULL;
}
memset(&sfx->decoder, 0, sizeof(sfx->decoder));
}
S_UnlockMixer();
}

View file

@ -30,6 +30,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <io.h>
#include <direct.h>
//#define RESTARTTEST
#ifdef MULTITHREAD
#include <process.h>
#endif
@ -51,6 +53,10 @@ unsigned int sys_parenttop;
unsigned int sys_parentwidth; //valid if sys_parentwindow is set
unsigned int sys_parentheight;
#ifdef RESTARTTEST
jmp_buf restart_jmpbuf;
#endif
/*
================
Sys_RandomBytes
@ -873,6 +879,10 @@ void Sys_Quit (void)
SV_Shutdown();
#endif
#ifdef RESTARTTEST
longjmp(restart_jmpbuf, 1);
#endif
#ifdef NPFTE
{
extern jmp_buf host_abort;
@ -1759,6 +1769,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
if (hPrevInstance)
return 0;
#ifndef MINGW
#if _MSC_VER > 1200
Win7_Init();
@ -1851,6 +1862,10 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
}
}
#ifdef RESTARTTEST
setjmp (restart_jmpbuf);
#endif
GetModuleFileName(NULL, cwd, sizeof(cwd)-1);
strcpy(exename, COM_SkipPath(cwd));
parms.argv = (const char **)argv;

View file

@ -25,7 +25,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// a pixel can be one, two, or four bytes
typedef qbyte pixel_t;
typedef enum {QR_NONE, QR_OPENGL, QR_DIRECT3D} r_qrenderer_t;
typedef enum {QR_NONE, QR_OPENGL, QR_DIRECT3D, QR_SOFTWARE} r_qrenderer_t;
typedef struct {
//you are not allowed to make anything not work if it's not based on these vars...

View file

@ -20,6 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// view.h
extern cvar_t v_gamma;
extern cvar_t v_contrast;
extern cvar_t lcd_x;
extern float sw_blend[4];
extern float hw_blend[4];

View file

@ -406,6 +406,15 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define NORETURN __attribute__((noreturn))
#endif
//I'm making my own restrict, because msvc can't cope if I #define restrict to __restrict, and quite possibly other platforms too
#if __STDC_VERSION__ >= 199901L
#define fte_restrict restrict
#elif defined(_MSC_VER)
#define fte_restrict __restrict
#else
#define fte_restrict
#endif
#ifndef FTE_DEPRECATED
#define FTE_DEPRECATED

View file

@ -858,7 +858,7 @@ typedef struct
int patchheight;
} rbspface_t;
#define MAX_ENT_LEAFS 16
#define MAX_ENT_LEAFS 32
typedef struct pvscache_s
{
int num_leafs;

View file

@ -988,7 +988,6 @@ typedef struct cmd_function_s
xcommand_t function;
qbyte restriction; //restriction of admin level
qbyte zmalloced;
} cmd_function_t;
@ -1438,44 +1437,8 @@ void Cmd_TokenizePunctation (char *text, char *punctuation)
Cmd_AddCommand
============
*/
qboolean Cmd_AddCommand (char *cmd_name, xcommand_t function)
{
cmd_function_t *cmd;
if (host_initialized) // because hunk allocation would get stomped
Sys_Error ("Cmd_AddCommand after host_initialized");
// fail if the command is a variable name
if (Cvar_VariableString(cmd_name)[0])
{
Con_Printf ("Cmd_AddCommand: %s already defined as a var\n", cmd_name);
return false;
}
// fail if the command already exists
for (cmd=cmd_functions ; cmd ; cmd=cmd->next)
{
if (!Q_strcmp (cmd_name, cmd->name))
{
if (cmd->function == function) //happens a lot with q3
Con_DPrintf ("Cmd_AddCommand: %s already defined\n", cmd_name);
else
Con_Printf ("Cmd_AddCommand: %s already defined\n", cmd_name);
return false;
}
}
cmd = (cmd_function_t*)Hunk_AllocName (sizeof(cmd_function_t), cmd_name);
cmd->name = cmd_name;
cmd->function = function;
cmd->next = cmd_functions;
cmd->restriction = 0;
cmd_functions = cmd;
return true;
}
qboolean Cmd_AddRemCommand (char *cmd_name, xcommand_t function)
qboolean Cmd_AddCommand (char *cmd_name, xcommand_t function)
{
cmd_function_t *cmd;
@ -1508,7 +1471,6 @@ qboolean Cmd_AddRemCommand (char *cmd_name, xcommand_t function)
cmd->function = function;
cmd->next = cmd_functions;
cmd->restriction = 0;
cmd->zmalloced = true;
cmd_functions = cmd;
return true;
@ -1530,11 +1492,6 @@ void Cmd_RemoveCommand (char *cmd_name)
if (!strcmp (cmd_name, cmd->name))
{
*back = cmd->next;
if (!cmd->zmalloced)
{
Con_Printf("Cmd_RemoveCommand: %s was not added dynamically\n", cmd_name);
return;
}
Z_Free (cmd);
return;
}
@ -2821,8 +2778,6 @@ void Cmd_WriteConfig_f(void)
Cvar_WriteVariables (f, true);
VFS_CLOSE(f);
FS_FlushFSHash();
Cvar_Saved();
}
@ -2889,13 +2844,19 @@ void Cmd_Condump_f(void)
void Cmd_Shutdown(void)
{
cmd_function_t *c;
cmdalias_t *a;
//make sure we get no other execution
int level;
for (level = 0; level < sizeof(cmd_text)/sizeof(cmd_text[0]); level++)
SZ_Clear (&cmd_text[level].buf);
cmd_functions = NULL;
while(cmd_functions)
{
c = cmd_functions;
cmd_functions = c->next;
Z_Free(c);
}
while(cmd_alias)
{
a = cmd_alias;
@ -3015,7 +2976,7 @@ void Cmd_Init (void)
Cvar_Register(&dpcompat_set, "Darkplaces compatibility");
#ifndef SERVERONLY
rcon_level.ival = atof(rcon_level.string); //client is restricted to not be allowed to change restrictions.
rcon_level.ival = atof(rcon_level.defaultstr); //client is restricted to not be allowed to change restrictions.
#else
Cvar_Register(&rcon_level, "Access controls"); //server gains versatility.
#endif

View file

@ -73,7 +73,6 @@ void Cmd_Shutdown(void);
void Cmd_StuffCmds (void);
void Cmd_RemoveCommand (char *cmd_name);
qboolean Cmd_AddRemCommand (char *cmd_name, xcommand_t function); //removable command
qboolean Cmd_AddCommand (char *cmd_name, xcommand_t function);
// called by the init functions of other parts of the program to
// register commands and functions to call for them.

View file

@ -351,11 +351,9 @@ static void PSKGenMatrix(float x, float y, float z, float qx, float qy, float qz
result[2*4+3] = z;
}
#define restrict
#if 0
/*transforms some skeletal vecV_t values*/
static void Alias_TransformVerticies_V(float *bonepose, int vertcount, qbyte *bidx, float *weights, float *xyzin, float *restrict xyzout)
static void Alias_TransformVerticies_V(float *bonepose, int vertcount, qbyte *bidx, float *weights, float *xyzin, float *fte_restrict xyzout)
{
int i;
float *matrix;
@ -395,8 +393,8 @@ static void Alias_TransformVerticies_V(float *bonepose, int vertcount, qbyte *bi
/*transforms some skeletal vecV_t values*/
static void Alias_TransformVerticies_VN(float *bonepose, int vertcount, qbyte *bidx, float *weights,
float *xyzin, float *restrict xyzout,
float *normin, float *restrict normout)
float *xyzin, float *fte_restrict xyzout,
float *normin, float *fte_restrict normout)
{
int i, j;
float *matrix;
@ -441,7 +439,7 @@ static void Alias_TransformVerticies_VN(float *bonepose, int vertcount, qbyte *b
#if 0
/*transforms some skeletal vec3_t values*/
static void Alias_TransformVerticies_3(float *bonepose, int vertcount, qbyte *bidx, float *weights, float *xyzin, float *restrict xyzout)
static void Alias_TransformVerticies_3(float *fte_restrict bonepose, int vertcount, qbyte *bidx, float *weights, float *xyzin, float *fte_restrict xyzout)
{
int i;
float *matrix;
@ -1347,14 +1345,14 @@ static void Alias_BuildSkeletalMesh(mesh_t *mesh, float *bonepose, galiasinfo_t
if (inf->ofs_skel_idx)
{
float *restrict xyzout = mesh->xyz_array[0];
float *restrict normout = mesh->normals_array[0];
qbyte *restrict bidx = (qbyte*)((char*)inf + inf->ofs_skel_idx);
float *restrict xyzin = (float*)((char*)inf + inf->ofs_skel_xyz);
float *restrict normin = (float*)((char*)inf + inf->ofs_skel_norm);
float *restrict svect = (float*)((char*)inf + inf->ofs_skel_svect);
float *restrict tvect = (float*)((char*)inf + inf->ofs_skel_tvect);
float *restrict weight = (float*)((char*)inf + inf->ofs_skel_weight);
float *fte_restrict xyzout = mesh->xyz_array[0];
float *fte_restrict normout = mesh->normals_array[0];
qbyte *fte_restrict bidx = (qbyte*)((char*)inf + inf->ofs_skel_idx);
float *fte_restrict xyzin = (float*)((char*)inf + inf->ofs_skel_xyz);
float *fte_restrict normin = (float*)((char*)inf + inf->ofs_skel_norm);
float *fte_restrict svect = (float*)((char*)inf + inf->ofs_skel_svect);
float *fte_restrict tvect = (float*)((char*)inf + inf->ofs_skel_tvect);
float *fte_restrict weight = (float*)((char*)inf + inf->ofs_skel_weight);
Alias_TransformVerticies_VN(bonepose, inf->numverts, bidx, weight, xyzin, xyzout, normin, normout);
// Alias_TransformVerticies_3(bonepose, inf->numverts, bidx, weight, svect, mesh->snormals_array[0]);
@ -1522,7 +1520,7 @@ qboolean Alias_GAliasBuildMesh(mesh_t *mesh, galiasinfo_t *inf, int surfnum, ent
#ifdef SKELETALMODELS
meshcache.usebonepose = NULL;
if (inf->ofs_skel_xyz && !inf->ofs_skel_weight)
if (inf->ofs_skel_xyz && 1)//!inf->ofs_skel_weight)
{
meshcache.usebonepose = NULL;
mesh->xyz_array = (vecV_t*)((char*)inf + inf->ofs_skel_xyz);
@ -1635,6 +1633,8 @@ qboolean Alias_GAliasBuildMesh(mesh_t *mesh, galiasinfo_t *inf, int surfnum, ent
if (r_shadow_realtime_world.ival || r_shadow_realtime_dlight.ival)
{
mesh->xyz2_array = NULL;
mesh->xyz_blendw[0] = 1;
mesh->xyz_blendw[1] = 0;
R_LerpFrames(mesh, (galiaspose_t *)((char *)g1 + g1->poseofs + sizeof(galiaspose_t)*frame1),
(galiaspose_t *)((char *)g2 + g2->poseofs + sizeof(galiaspose_t)*frame2),
1-lerp, e->fatness);
@ -2815,13 +2815,15 @@ qboolean Mod_LoadQ1Model (model_t *mod, void *buffer)
switch(qrenderer)
{
default:
#if defined(GLQUAKE) || defined(D3DQUAKE)
case QR_DIRECT3D:
case QR_OPENGL:
case QR_SOFTWARE:
pinstverts = (dstvert_t *)Q1_LoadSkins_GL(skinstart, skintranstype);
break;
#endif
default:
case QR_NONE:
pinstverts = (dstvert_t *)Q1_LoadSkins_SV(skinstart, skintranstype);
break;
}
@ -4022,7 +4024,6 @@ qboolean Mod_LoadQ3Model(model_t *mod, void *buffer)
externalskins = LittleLong(surf->numShaders);
if (externalskins)
{
//extern int gl_bumpmappingpossible; // unused variable
char shadname[1024];
skin = Hunk_Alloc((LittleLong(surf->numShaders)+externalskins)*((sizeof(galiasskin_t)+sizeof(shader_t*))));
@ -5689,7 +5690,7 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer)
unsigned short *framedata;
vecV_t *opos;
vec3_t *onorm;
vec3_t *onorm1, *onorm2, *onorm3;
vec4_t *oweight;
byte_vec4_t *oindex;
float *opose;
@ -5774,19 +5775,21 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer)
sizeof(*skin)*h->num_meshes + sizeof(*shaders)*h->num_meshes +
#endif
sizeof(*fgroup)*(baseposeonly?1:h->num_anims) + sizeof(float)*12*(baseposeonly?h->num_joints:(h->num_poses*h->num_frames)) + sizeof(*bones)*h->num_joints +
(sizeof(*opos) + sizeof(*onorm) + sizeof(*otcoords) + (noweights?0:(sizeof(*oindex)+sizeof(*oweight)))) * h->num_vertexes);
(sizeof(*opos) + sizeof(*onorm1) + sizeof(*onorm2) + sizeof(*onorm3) + sizeof(*otcoords) + (noweights?0:(sizeof(*oindex)+sizeof(*oweight)))) * h->num_vertexes);
bones = (galiasbone_t*)(gai + h->num_meshes);
opos = (vecV_t*)(bones + h->num_joints);
onorm = (vec3_t*)(opos + h->num_vertexes);
onorm3 = (vec3_t*)(opos + h->num_vertexes);
onorm2 = (vec3_t*)(onorm3 + h->num_vertexes);
onorm1 = (vec3_t*)(onorm2 + h->num_vertexes);
if (noweights)
{
oindex = NULL;
oweight = NULL;
otcoords = (vec2_t*)(onorm + h->num_vertexes);
otcoords = (vec2_t*)(onorm1 + h->num_vertexes);
}
else
{
oindex = (byte_vec4_t*)(onorm + h->num_vertexes);
oindex = (byte_vec4_t*)(onorm1 + h->num_vertexes);
oweight = (vec4_t*)(oindex + h->num_vertexes);
otcoords = (vec2_t*)(oweight + h->num_vertexes);
}
@ -5961,9 +5964,9 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer)
gai[i].shares_verts = i;
gai[i].numverts = LittleLong(mesh[i].num_vertexes);
gai[i].ofs_skel_xyz = (char*)(opos+offset) - (char*)&gai[i];
gai[i].ofs_skel_norm = (char*)(onorm+offset) - (char*)&gai[i];
gai[i].ofs_skel_svect = 0;
gai[i].ofs_skel_tvect = 0;
gai[i].ofs_skel_norm = vnorm?(char*)(onorm1+offset) - (char*)&gai[i]:0;
gai[i].ofs_skel_svect = (vnorm&&vtang)?(char*)(onorm2+offset) - (char*)&gai[i]:0;
gai[i].ofs_skel_tvect = (vnorm&&vtang)?(char*)(onorm3+offset) - (char*)&gai[i]:0;
gai[i].ofs_skel_idx = oindex?(char*)(oindex+offset) - (char*)&gai[i]:0;
gai[i].ofs_skel_weight = oweight?(char*)(oweight+offset) - (char*)&gai[i]:0;
}
@ -5979,7 +5982,18 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer)
{
Vector2Copy(tcoord+i*2, otcoords[i]);
VectorCopy(vpos+i*3, opos[i]);
VectorCopy(vnorm+i*4, onorm[i]);
if (vnorm)
{
VectorCopy(vnorm+i*3, onorm1[i]);
}
if (vnorm && vtang)
{
VectorCopy(vtang+i*4, onorm2[i]);
if(LittleFloat(vtang[i*4 + 3]) < 0)
CrossProduct(onorm2[i], onorm1[i], onorm3[i]);
else
CrossProduct(onorm1[i], onorm2[i], onorm3[i]);
}
}
return gai;
}

View file

@ -3358,9 +3358,9 @@ void COM_Init (void)
COM_CheckRegistered ();
if (static_registered)
registered.string = "1";
registered.defaultstr = "1";
else
registered.string = "0";
registered.defaultstr = "0";
Cvar_Register (&registered, "Copy protection");
Cvar_Register (&gameversion, "Gamecode");

View file

@ -369,7 +369,9 @@ enum fs_relative{
FS_SKINS //qw/skins/
};
void FS_FlushFSHash(void);
void FS_FlushFSHashReally(void);
void FS_FlushFSHashWritten(void);
void FS_FlushFSHashRemoved(void);
void FS_CreatePath(const char *pname, enum fs_relative relativeto);
qboolean FS_Rename(const char *oldf, const char *newf, enum fs_relative relativeto); //0 on success, non-0 on error
qboolean FS_Rename2(const char *oldf, const char *newf, enum fs_relative oldrelativeto, enum fs_relative newrelativeto);

View file

@ -71,11 +71,10 @@ typedef struct cvar_s
void (*callback) (struct cvar_s *var, char *oldvalue);
char *description;
char *defaultstr; //default
int ival;
char *defaultstr; //default
qbyte restriction;
#ifdef HLSERVER
@ -85,9 +84,9 @@ typedef struct cvar_s
} cvar_t;
#ifdef MINIMAL
#define CVARAFDC(ConsoleName,Value,ConsoleName2,Flags,Description,Callback) {ConsoleName, Value, NULL, Flags, 0, 0, 0, ConsoleName2, Callback, NULL}
#define CVARAFDC(ConsoleName,Value,ConsoleName2,Flags,Description,Callback) {ConsoleName, NULL, NULL, Flags, 0, 0, 0, ConsoleName2, Callback, NULL, Value}
#else
#define CVARAFDC(ConsoleName,Value,ConsoleName2,Flags,Description,Callback) {ConsoleName, Value, NULL, Flags, 0, 0, 0, ConsoleName2, Callback, Description}
#define CVARAFDC(ConsoleName,Value,ConsoleName2,Flags,Description,Callback) {ConsoleName, NULL, NULL, Flags, 0, 0, 0, ConsoleName2, Callback, Description, Value}
#endif
#define CVARAFD(ConsoleName,Value,ConsoleName2,Flags,Description)CVARAFDC(ConsoleName, Value, ConsoleName2, Flags, Description, NULL)
#define CVARAFC(ConsoleName,Value,ConsoleName2,Flags,Callback) CVARAFC(ConsoleName, Value, ConsoleName2, Flags, NULL, Callback)

View file

@ -413,21 +413,22 @@ static void COM_CopyFile (char *netpath, char *cachepath)
int fs_hash_dups;
int fs_hash_files;
void FS_FlushFSHash(void)
void FS_FlushFSHashReally(void)
{
if (filesystemhash.numbuckets)
{
int i;
bucket_t *bucket, *next;
fsbucket_t *bucket, *next;
for (i = 0; i < filesystemhash.numbuckets; i++)
{
bucket = filesystemhash.bucket[i];
bucket = (fsbucket_t*)filesystemhash.bucket[i];
filesystemhash.bucket[i] = NULL;
while(bucket)
{
next = bucket->next;
if (bucket->key.string == (char*)(bucket+1))
next = (fsbucket_t*)bucket->buck.next;
/*if the string starts right after the bucket, free it*/
if (bucket->depth < 0)
Z_Free(bucket);
bucket = next;
}
@ -436,9 +437,53 @@ void FS_FlushFSHash(void)
com_fschanged = true;
}
void FS_FlushFSHashWritten(void)
{
/*automatically handled*/
}
void FS_FlushFSHashRemoved(void)
{
FS_FlushFSHashReally();
}
void FS_AddFileHash(int depth, const char *fname, fsbucket_t *filehandle, void *pathhandle)
{
fsbucket_t *old;
old = Hash_GetInsensativeBucket(&filesystemhash, fname);
if (old)
{
fs_hash_dups++;
if (depth >= ((old->depth<0)?(-old->depth-1):old->depth))
{
return;
}
//remove the old version
Hash_RemoveBucket(&filesystemhash, fname, &old->buck);
if (old->depth < 0)
Z_Free(old);
}
if (!filehandle)
{
filehandle = Z_Malloc(sizeof(*filehandle) + strlen(fname)+1);
if (!filehandle)
return; //eep!
strcpy((char*)(filehandle+1), fname);
fname = (char*)(filehandle+1);
filehandle->depth = -depth-1;
}
else filehandle->depth = depth;
Hash_AddInsensative(&filesystemhash, fname, pathhandle, &filehandle->buck);
fs_hash_files++;
}
void FS_RebuildFSHash(void)
{
int depth = 1;
searchpath_t *search;
if (!filesystemhash.numbuckets)
{
@ -447,7 +492,7 @@ void FS_RebuildFSHash(void)
}
else
{
FS_FlushFSHash();
FS_FlushFSHashRemoved();
}
Hash_InitTable(&filesystemhash, filesystemhash.numbuckets, filesystemhash.bucket);
@ -458,12 +503,12 @@ void FS_RebuildFSHash(void)
{ //go for the pure paths first.
for (search = com_purepaths; search; search = search->nextpure)
{
search->funcs->BuildHash(search->handle);
search->funcs->BuildHash(search->handle, depth++);
}
}
for (search = com_searchpaths ; search ; search = search->next)
{
search->funcs->BuildHash(search->handle);
search->funcs->BuildHash(search->handle, depth++);
}
com_fschanged = false;
@ -1217,7 +1262,7 @@ void COM_FlushTempoaryPacks(void)
sp = *link;
if (sp->istemporary)
{
FS_FlushFSHash();
FS_FlushFSHashReally();
*link = sp->next;
@ -1422,7 +1467,10 @@ static searchpath_t *FS_AddPathHandle(const char *purepath, const char *probable
search->isexplicit = isexplicit;
search->handle = handle;
search->funcs = funcs;
Q_strncpyz(search->purepath, purepath, sizeof(search->purepath));
if (funcs == &osfilefuncs)
Q_strncpyz(search->purepath, probablepath, sizeof(search->purepath));
else
Q_strncpyz(search->purepath, purepath, sizeof(search->purepath));
if (istemporary)
{
@ -1466,8 +1514,15 @@ void COM_RefreshFSCache_f(void)
void COM_FlushFSCache(void)
{
searchpath_t *search;
if (com_fs_cache.ival != 2)
com_fschanged=true;
{
for (search = com_searchpaths ; search ; search = search->next)
{
if (search->funcs->PollChanges)
com_fschanged |= search->funcs->PollChanges(search->handle);
}
}
}
/*since should start as 0, otherwise this can be used to poll*/
@ -1494,6 +1549,7 @@ void FS_AddGameDirectory (const char *puredir, const char *dir, unsigned int loa
searchpath_t *search;
char *p;
void *handle;
fs_restarts++;
@ -1514,9 +1570,8 @@ void FS_AddGameDirectory (const char *puredir, const char *dir, unsigned int loa
// add the directory to the search path
//
p = Z_Malloc(strlen(dir)+1);
strcpy(p, dir);
FS_AddPathHandle((*dir?puredir:""), va("%s/", dir), &osfilefuncs, p, false, false, true, loadstuff);
handle = osfilefuncs.OpenNew(NULL, dir);
FS_AddPathHandle((*dir?puredir:""), va("%s/", dir), &osfilefuncs, handle, false, false, true, loadstuff);
}
char *COM_NextPath (char *prevpath)
@ -1531,8 +1586,8 @@ char *COM_NextPath (char *prevpath)
continue;
if (prevpath == prev)
return s->handle;
prev = s->handle;
return s->purepath;
prev = s->purepath;
}
return NULL;
@ -1655,7 +1710,7 @@ void COM_Gamedir (const char *dir)
FS_ForceToPure(NULL, NULL, 0);
#ifndef SERVERONLY
Host_WriteConfiguration(); //before we change anything.
// Host_WriteConfiguration(); //before we change anything.
#endif
Q_strncpyz (gamedirfile, dir, sizeof(gamedirfile));
@ -1667,7 +1722,7 @@ void COM_Gamedir (const char *dir)
cl.gamedirchanged = true;
#endif
FS_FlushFSHash();
FS_FlushFSHashReally();
//
// free up any current game dir info
@ -1867,7 +1922,7 @@ void FS_ImpurePacks(const char *names, const char *crcs)
break;
sp = FS_AddPathHandle(pname, local, searchpathformats[i].funcs, handle, true, true, false, (unsigned int)-1);
FS_FlushFSHash();
FS_FlushFSHashReally();
break;
}
}
@ -1899,7 +1954,7 @@ void FS_ForceToPure(const char *names, const char *crcs, int seed)
{
Con_Printf("Pure FS deactivated\n");
com_purepaths = NULL;
FS_FlushFSHash();
FS_FlushFSHashReally();
}
return;
}
@ -1993,7 +2048,7 @@ void FS_ForceToPure(const char *names, const char *crcs, int seed)
}
}
FS_FlushFSHash();
FS_FlushFSHashReally();
if (com_purepaths && !waspure)
Con_Printf("Pure FS activated\n");
@ -2055,7 +2110,7 @@ void FS_ReloadPackFilesFlags(unsigned int reloadflags)
}
#endif
FS_FlushFSHash();
FS_FlushFSHashReally();
oldpaths = com_searchpaths;
com_searchpaths = NULL;
@ -2360,7 +2415,7 @@ qboolean Sys_FindGameData(const char *poshname, const char *gamename, char *base
void FS_Shutdown(void)
{
searchpath_t *next;
FS_FlushFSHash();
FS_FlushFSHashReally();
//
// free up any current game dir info

View file

@ -1,4 +1,9 @@
#include "hash.h"
typedef struct
{
bucket_t buck;
int depth; /*shallower files will remove deeper files*/
} fsbucket_t;
extern hashtable_t filesystemhash; //this table is the one to build your hash references into
extern int fs_hash_dups; //for tracking efficiency. no functional use.
extern int fs_hash_files; //for tracking efficiency. no functional use.
@ -7,7 +12,7 @@ extern int fs_hash_files; //for tracking efficiency. no functional use.
typedef struct {
void (*PrintPath)(void *handle);
void (*ClosePath)(void *handle);
void (*BuildHash)(void *handle);
void (*BuildHash)(void *handle, int depth);
qboolean (*FindFile)(void *handle, flocation_t *loc, const char *name, void *hashedresult); //true if found (hashedresult can be NULL)
//note that if rawfile and offset are set, many Com_FileOpens will read the raw file
//otherwise ReadFile will be called instead.
@ -19,6 +24,8 @@ typedef struct {
int (*GeneratePureCRC) (void *handle, int seed, int usepure);
vfsfile_t *(*OpenVFS)(void *handle, flocation_t *loc, const char *mode);
qboolean (*PollChanges)(void *handle); //returns true if there were changes
} searchpathfuncs_t;
//the stdio filesystem is special as that's the starting point of the entire filesystem
@ -27,5 +34,7 @@ extern searchpathfuncs_t osfilefuncs;
vfsfile_t *VFSOS_Open(const char *osname, const char *mode);
vfsfile_t *FS_DecompressGZip(vfsfile_t *infile);
void FS_AddFileHash(int depth, const char *fname, fsbucket_t *filehandle, void *pathhandle); //called inside the BuildHash function
int FS_RegisterFileSystemType(const char *extension, searchpathfuncs_t *funcs, qboolean loadscan);
void FS_UnRegisterFileSystemType(int idx);

View file

@ -7,11 +7,11 @@
typedef struct
{
fsbucket_t bucket;
char name[MAX_QPATH];
int filepos, filelen;
bucket_t bucket;
} packfile_t;
} mpackfile_t;
typedef struct pack_s
{
@ -19,7 +19,7 @@ typedef struct pack_s
vfsfile_t *handle;
unsigned int filepos; //the pos the subfiles left it at (to optimize calls to vfs_seek)
int numfiles;
packfile_t *files;
mpackfile_t *files;
int references; //seeing as all vfiles from a pak file use the parent's vfsfile, we need to keep the parent open until all subfiles are closed.
} pack_t;
@ -77,25 +77,19 @@ void FSPAK_ClosePath(void *handle)
Z_Free(pak->files);
Z_Free(pak);
}
void FSPAK_BuildHash(void *handle)
void FSPAK_BuildHash(void *handle, int depth)
{
pack_t *pak = handle;
int i;
for (i = 0; i < pak->numfiles; i++)
{
if (!Hash_GetInsensative(&filesystemhash, pak->files[i].name))
{
fs_hash_files++;
Hash_AddInsensative(&filesystemhash, pak->files[i].name, &pak->files[i], &pak->files[i].bucket);
}
else
fs_hash_dups++;
FS_AddFileHash(depth, pak->files[i].name, &pak->files[i].bucket, &pak->files[i]);
}
}
qboolean FSPAK_FLocate(void *handle, flocation_t *loc, const char *filename, void *hashedresult)
{
packfile_t *pf = hashedresult;
mpackfile_t *pf = hashedresult;
int i, len;
pack_t *pak = handle;
@ -193,7 +187,7 @@ void *FSPAK_LoadPackFile (vfsfile_t *file, const char *desc)
dpackheader_t header;
int i;
// int j;
packfile_t *newfiles;
mpackfile_t *newfiles;
int numpackfiles;
pack_t *pack;
vfsfile_t *packhandle;
@ -224,7 +218,7 @@ void *FSPAK_LoadPackFile (vfsfile_t *file, const char *desc)
// if (numpackfiles != PAK0_COUNT)
// com_modified = true; // not the original file
newfiles = (packfile_t*)Z_Malloc (numpackfiles * sizeof(packfile_t));
newfiles = (mpackfile_t*)Z_Malloc (numpackfiles * sizeof(mpackfile_t));
VFS_SEEK(packhandle, header.dirofs);
// fread (&info, 1, header.dirlen, packhandle);

View file

@ -9,12 +9,15 @@
#define Z_Malloc malloc
#else
#if !defined(_WIN32) || defined(_SDL)
#define VFSSTDIO_Open VFSOS_Open
#define stdiofilefuncs osfilefuncs
#endif
#define FSSTDIO_OpenTemp FS_OpenTemp
#endif
typedef struct {
int depth;
char rootpath[1];
} stdiopath_t;
typedef struct {
vfsfile_t funcs;
FILE *handle;
@ -115,7 +118,7 @@ vfsfile_t *FSSTDIO_OpenTemp(void)
vfsfile_t *Sys_OpenAsset(const char *fname);
#endif
vfsfile_t *VFSSTDIO_Open(const char *osname, const char *mode)
static vfsfile_t *VFSSTDIO_Open(const char *osname, const char *mode, qboolean *needsflush)
{
FILE *f;
vfsstdiofile_t *file;
@ -126,6 +129,9 @@ vfsfile_t *VFSSTDIO_Open(const char *osname, const char *mode)
char newmode[3];
int modec = 0;
if (needsflush)
*needsflush = false;
#if 0//def ANDROID
// if (!strncmp("asset/", osname, 6))
{
@ -151,6 +157,12 @@ vfsfile_t *VFSSTDIO_Open(const char *osname, const char *mode)
if (!f)
return NULL;
if (write || append)
{
if (needsflush)
*needsflush = true;
}
file = Z_Malloc(sizeof(vfsstdiofile_t));
file->funcs.ReadBytes = strchr(mode, 'r')?VFSSTDIO_ReadBytes:NULL;
file->funcs.WriteBytes = (strchr(mode, 'w')||strchr(mode, 'a'))?VFSSTDIO_WriteBytes:NULL;
@ -164,29 +176,67 @@ vfsfile_t *VFSSTDIO_Open(const char *osname, const char *mode)
return (vfsfile_t*)file;
}
#if !defined(_WIN32) || defined(_SDL)
vfsfile_t *VFSOS_Open(const char *osname, const char *mode)
{
vfsfile_t *f;
qboolean needsflush;
f = VFSSTDIO_Open(osname, mode, &needsflush);
if (needsflush)
FS_FlushFSHashReally();
return f;
}
#endif
#ifndef WEBSVONLY
static vfsfile_t *FSSTDIO_OpenVFS(void *handle, flocation_t *loc, const char *mode)
{
vfsfile_t *f;
stdiopath_t *sp = handle;
char diskname[MAX_OSPATH];
qboolean needsflush;
//path is already cleaned, as anything that gets a valid loc needs cleaning up first.
snprintf(diskname, sizeof(diskname), "%s/%s", (char*)handle, loc->rawname);
snprintf(diskname, sizeof(diskname), "%s/%s", sp->rootpath, loc->rawname);
return VFSOS_Open(diskname, mode);
f = VFSSTDIO_Open(diskname, mode, &needsflush);
if (needsflush)
FS_AddFileHash(sp->depth, loc->rawname, NULL, sp);
return f;
}
static void FSSTDIO_PrintPath(void *handle)
{
Con_Printf("%s\n", (char*)handle);
stdiopath_t *np = handle;
Con_Printf("%s\n", np->rootpath);
}
static void FSSTDIO_ClosePath(void *handle)
{
Z_Free(handle);
}
static qboolean FSSTDIO_PollChanges(void *handle)
{
stdiopath_t *np = handle;
return true; //can't verify that or not, so we have to assume the worst
}
static void *FSSTDIO_OpenPath(vfsfile_t *mustbenull, const char *desc)
{
stdiopath_t *np;
int dlen = strlen(desc);
if (mustbenull)
return NULL;
np = Z_Malloc(sizeof(*np) + dlen);
if (np)
{
np->depth = 0;
memcpy(np->rootpath, desc, dlen+1);
}
return np;
}
static int FSSTDIO_RebuildFSHash(const char *filename, int filesize, void *data)
{
stdiopath_t *sp = data;
if (filename[strlen(filename)-1] == '/')
{ //this is actually a directory
@ -195,27 +245,18 @@ static int FSSTDIO_RebuildFSHash(const char *filename, int filesize, void *data)
Sys_EnumerateFiles((char*)data, childpath, FSSTDIO_RebuildFSHash, data);
return true;
}
if (!Hash_GetInsensative(&filesystemhash, filename))
{
bucket_t *bucket = (bucket_t*)BZ_Malloc(sizeof(bucket_t) + strlen(filename)+1);
strcpy((char *)(bucket+1), filename);
#ifdef _WIN32
Q_strlwr((char *)(bucket+1));
#endif
Hash_AddInsensative(&filesystemhash, (char *)(bucket+1), data, bucket);
fs_hash_files++;
}
else
fs_hash_dups++;
FS_AddFileHash(sp->depth, filename, NULL, sp);
return true;
}
static void FSSTDIO_BuildHash(void *handle)
static void FSSTDIO_BuildHash(void *handle, int depth)
{
Sys_EnumerateFiles(handle, "*", FSSTDIO_RebuildFSHash, handle);
stdiopath_t *sp = handle;
sp->depth = depth;
Sys_EnumerateFiles(sp->rootpath, "*", FSSTDIO_RebuildFSHash, handle);
}
static qboolean FSSTDIO_FLocate(void *handle, flocation_t *loc, const char *filename, void *hashedresult)
{
stdiopath_t *sp = handle;
int len;
char netpath[MAX_OSPATH];
@ -232,7 +273,7 @@ static qboolean FSSTDIO_FLocate(void *handle, flocation_t *loc, const char *file
*/
// check a file in the directory tree
snprintf (netpath, sizeof(netpath)-1, "%s/%s",(char*)handle, filename);
snprintf (netpath, sizeof(netpath)-1, "%s/%s", sp->rootpath, filename);
#ifdef ANDROID
{
@ -291,9 +332,10 @@ searchpathfuncs_t stdiofilefuncs = {
FSSTDIO_FLocate,
FSSTDIO_ReadFile,
FSSTDIO_EnumerateFiles,
FSSTDIO_OpenPath,
NULL,
NULL,
FSSTDIO_OpenVFS
FSSTDIO_OpenVFS,
FSSTDIO_PollChanges
};
#endif
#endif

View file

@ -12,6 +12,11 @@
#define VFSW32_Open VFSOS_Open
#define w32filefuncs osfilefuncs
typedef struct {
HANDLE changenotification;
int hashdepth;
char rootpath[1];
} vfsw32path_t;
typedef struct {
vfsfile_t funcs;
HANDLE hand;
@ -102,6 +107,8 @@ static void VFSW32_Close(vfsfile_t *file)
}
CloseHandle(intfile->hand);
Z_Free(file);
COM_FlushFSCache();
}
vfsfile_t *VFSW32_Open(const char *osname, const char *mode)
@ -183,49 +190,86 @@ static vfsfile_t *VFSW32_OpenVFS(void *handle, flocation_t *loc, const char *mod
static void VFSW32_PrintPath(void *handle)
{
Con_Printf("%s\n", (char *)handle);
vfsw32path_t *wp = handle;
Con_Printf("%s\n", wp->rootpath);
}
static void VFSW32_ClosePath(void *handle)
{
Z_Free(handle);
vfsw32path_t *wp = handle;
if (wp->changenotification != INVALID_HANDLE_VALUE)
FindCloseChangeNotification(wp->changenotification);
Z_Free(wp);
}
static int VFSW32_RebuildFSHash(const char *filename, int filesize, void *data)
static qboolean VFSW32_PollChanges(void *handle)
{
qboolean result = false;
vfsw32path_t *wp = handle;
if (wp->changenotification == INVALID_HANDLE_VALUE)
return true;
for(;;)
{
switch(WaitForSingleObject(wp->changenotification, 0))
{
case WAIT_OBJECT_0:
result = true;
break;
case WAIT_TIMEOUT:
return result;
default:
FindCloseChangeNotification(wp->changenotification);
wp->changenotification = INVALID_HANDLE_VALUE;
return true;
}
FindNextChangeNotification(wp->changenotification);
}
return result;
}
static void *VFSW32_OpenPath(vfsfile_t *mustbenull, const char *desc)
{
vfsw32path_t *np;
int dlen = strlen(desc);
if (mustbenull)
return NULL;
np = Z_Malloc(sizeof(*np) + dlen);
if (np)
{
memcpy(np->rootpath, desc, dlen+1);
np->changenotification = FindFirstChangeNotification(np->rootpath, true, FILE_NOTIFY_CHANGE_FILE_NAME);
}
return np;
}
static int VFSW32_RebuildFSHash(const char *filename, int filesize, void *handle)
{
vfsw32path_t *wp = handle;
if (filename[strlen(filename)-1] == '/')
{ //this is actually a directory
char childpath[256];
Q_snprintfz(childpath, sizeof(childpath), "%s*", filename);
Sys_EnumerateFiles((char*)data, childpath, VFSW32_RebuildFSHash, data);
Sys_EnumerateFiles(wp->rootpath, childpath, VFSW32_RebuildFSHash, wp);
return true;
}
if (!Hash_GetInsensative(&filesystemhash, filename))
{
bucket_t *bucket = (bucket_t*)BZ_Malloc(sizeof(bucket_t) + strlen(filename)+1);
strcpy((char *)(bucket+1), filename);
#ifdef _WIN32
Q_strlwr((char *)(bucket+1));
#endif
Hash_AddInsensative(&filesystemhash, (char *)(bucket+1), data, bucket);
fs_hash_files++;
}
else
fs_hash_dups++;
FS_AddFileHash(wp->hashdepth, filename, NULL, wp);
return true;
}
static void VFSW32_BuildHash(void *handle)
static void VFSW32_BuildHash(void *handle, int hashdepth)
{
Sys_EnumerateFiles(handle, "*", VFSW32_RebuildFSHash, handle);
vfsw32path_t *wp = handle;
wp->hashdepth = hashdepth;
Sys_EnumerateFiles(wp->rootpath, "*", VFSW32_RebuildFSHash, handle);
}
static qboolean VFSW32_FLocate(void *handle, flocation_t *loc, const char *filename, void *hashedresult)
{
vfsw32path_t *wp = handle;
FILE *f;
int len;
char netpath[MAX_OSPATH];
if (hashedresult && (void *)hashedresult != handle)
if (hashedresult && (void *)hashedresult != wp)
return false;
/*
@ -237,7 +281,7 @@ static qboolean VFSW32_FLocate(void *handle, flocation_t *loc, const char *filen
*/
// check a file in the directory tree
snprintf (netpath, sizeof(netpath)-1, "%s/%s",(char*)handle, filename);
snprintf (netpath, sizeof(netpath)-1, "%s/%s", wp->rootpath, filename);
f = fopen(netpath, "rb");
if (!f)
@ -251,13 +295,15 @@ static qboolean VFSW32_FLocate(void *handle, flocation_t *loc, const char *filen
loc->len = len;
loc->offset = 0;
loc->index = 0;
snprintf(loc->rawname, sizeof(loc->rawname), "%s/%s", (char*)handle, filename);
snprintf(loc->rawname, sizeof(loc->rawname), "%s/%s", wp->rootpath, filename);
}
return true;
}
static void VFSW32_ReadFile(void *handle, flocation_t *loc, char *buffer)
{
// vfsw32path_t *wp = handle;
FILE *f;
f = fopen(loc->rawname, "rb");
if (!f) //err...
@ -268,9 +314,11 @@ static void VFSW32_ReadFile(void *handle, flocation_t *loc, char *buffer)
}
static int VFSW32_EnumerateFiles (void *handle, const char *match, int (*func)(const char *, int, void *), void *parm)
{
return Sys_EnumerateFiles(handle, match, func, parm);
vfsw32path_t *wp = handle;
return Sys_EnumerateFiles(wp->rootpath, match, func, parm);
}
searchpathfuncs_t w32filefuncs = {
VFSW32_PrintPath,
VFSW32_ClosePath,
@ -278,7 +326,8 @@ searchpathfuncs_t w32filefuncs = {
VFSW32_FLocate,
VFSW32_ReadFile,
VFSW32_EnumerateFiles,
VFSW32_OpenPath,
NULL,
NULL,
VFSW32_OpenVFS
VFSW32_OpenVFS,
VFSW32_PollChanges
};

View file

@ -214,10 +214,9 @@ vfsfile_t *FS_DecompressGZip(vfsfile_t *infile)
typedef struct
{
fsbucket_t bucket;
char name[MAX_QPATH];
int filepos, filelen;
bucket_t bucket;
} zpackfile_t;
@ -261,20 +260,14 @@ static void FSZIP_ClosePath(void *handle)
Z_Free(zip->files);
Z_Free(zip);
}
static void FSZIP_BuildHash(void *handle)
static void FSZIP_BuildHash(void *handle, int depth)
{
zipfile_t *zip = handle;
int i;
for (i = 0; i < zip->numfiles; i++)
{
if (!Hash_GetInsensative(&filesystemhash, zip->files[i].name))
{
fs_hash_files++;
Hash_AddInsensative(&filesystemhash, zip->files[i].name, &zip->files[i], &zip->files[i].bucket);
}
else
fs_hash_dups++;
FS_AddFileHash(depth, zip->files[i].name, &zip->files[i].bucket, &zip->files[i]);
}
}
static qboolean FSZIP_FLocate(void *handle, flocation_t *loc, const char *filename, void *hashedresult)

View file

@ -937,6 +937,14 @@ void Matrix4x4_CM_Transform3(const float *matrix, const float *vector, float *pr
product[1] = matrix[1]*vector[0] + matrix[5]*vector[1] + matrix[9]*vector[2] + matrix[13];
product[2] = matrix[2]*vector[0] + matrix[6]*vector[1] + matrix[10]*vector[2] + matrix[14];
}
void Matrix4x4_CM_Transform34(const float *matrix, const vec3_t vector, vec4_t product)
{
//transform as though vector[3] == 1
product[0] = matrix[0]*vector[0] + matrix[4]*vector[1] + matrix[8]*vector[2] + matrix[12];
product[1] = matrix[1]*vector[0] + matrix[5]*vector[1] + matrix[9]*vector[2] + matrix[13];
product[2] = matrix[2]*vector[0] + matrix[6]*vector[1] + matrix[10]*vector[2] + matrix[14];
product[3] = matrix[3]*vector[0] + matrix[7]*vector[1] + matrix[11]*vector[2] + matrix[15];
}
void Matrix4x4_CM_ModelViewMatrix(float *modelview, const vec3_t viewangles, const vec3_t vieworg)
{

View file

@ -78,6 +78,7 @@ extern vec3_t vec3_origin;
#define VectorInterpolate(a, bness, b, c) FloatInterpolate((a)[0], bness, (b)[0], (c)[0]),FloatInterpolate((a)[1], bness, (b)[1], (c)[1]),FloatInterpolate((a)[2], bness, (b)[2], (c)[2])
#define Vector2Copy(a,b) {(b)[0]=(a)[0];(b)[1]=(a)[1];}
#define Vector2Set(r,x,y) {(r)[0] = x; (r)[1] = y;}
#define Vector2Interpolate(a, bness, b, c) FloatInterpolate((a)[0], bness, (b)[0], (c)[0]),FloatInterpolate((a)[1], bness, (b)[1], (c)[1])
#define Vector4Copy(a,b) do{(b)[0]=(a)[0];(b)[1]=(a)[1];(b)[2]=(a)[2];(b)[3]=(a)[3];}while(0)
#define Vector4Scale(in,scale,out) ((out)[0]=(in)[0]*scale,(out)[1]=(in)[1]*scale,(out)[2]=(in)[2]*scale,(out)[3]=(in)[3]*scale)
@ -157,6 +158,7 @@ void Matrix3x4_Multiply(const float *a, const float *b, float *out);
void Matrix4x4_CM_Project (const vec3_t in, vec3_t out, const vec3_t viewangles, const vec3_t vieworg, float fovx, float fovy);
void Matrix4x4_CM_Transform3 (const float *matrix, const float *vector, float *product);
void Matrix4x4_CM_Transform4 (const float *matrix, const float *vector, float *product);
void Matrix4x4_CM_Transform34(const float *matrix, const vec3_t vector, vec4_t product);
void Matrix4x4_CM_UnProject (const vec3_t in, vec3_t out, const vec3_t viewangles, const vec3_t vieworg, float fovx, float fovy);
void Matrix3x4_RM_FromVectors(float *out, const float vx[3], const float vy[3], const float vz[3], const float t[3]);
void Matrix4x4_RM_FromVectors(float *out, const float vx[3], const float vy[3], const float vz[3], const float t[3]);

View file

@ -847,12 +847,18 @@ qboolean Netchan_Process (netchan_t *chan)
}
if (chan->incoming_unreliable != sequence)
{
if (chan->in_fragment_length && showdrop.ival)
Con_Printf("final fragment lost (%i). dropping entire packet\n", offset);
/*sequence doesn't match, forget the old*/
chan->in_fragment_length = 0;
chan->incoming_unreliable = sequence;
}
if (offset != chan->in_fragment_length)
{
if (showdrop.ival)
Con_Printf("prior fragment lost (%i-%i). dropping entire packet\n", offset, chan->in_fragment_length);
return false; /*dropped one*/
}
memcpy(chan->in_fragment_buf + offset, net_message.data + msg_readcount, len);
chan->in_fragment_length += len;

View file

@ -85,7 +85,7 @@ extern cvar_t sv_public, sv_listen_qw, sv_listen_nq, sv_listen_dp, sv_listen_q3;
static qboolean allowconnects = false;
#define MAX_LOOPBACK 4
#define MAX_LOOPBACK 8
typedef struct
{
qbyte data[MAX_UDP_PACKET];
@ -1399,7 +1399,12 @@ qboolean NET_GetLoopPacket (netsrc_t sock, netadr_t *from, sizebuf_t *message)
loop = &loopbacks[sock];
if (loop->send - loop->get > MAX_LOOPBACK)
{
extern cvar_t showdrop;
if (showdrop.ival)
Con_Printf("loopback dropping %i packets\n", (loop->send - MAX_LOOPBACK) - loop->get);
loop->get = loop->send - MAX_LOOPBACK;
}
if (loop->get >= loop->send)
return false;

View file

@ -716,7 +716,7 @@ qintptr_t VARGS Plug_Cmd_AddCommand(void *offset, quintptr_t mask, const qintptr
}
Q_strncpyz(plugincommandarray[i].command, name, sizeof(plugincommandarray[i].command));
if (!Cmd_AddRemCommand(plugincommandarray[i].command, Plug_Command_f))
if (!Cmd_AddCommand(plugincommandarray[i].command, Plug_Command_f))
return false;
plugincommandarray[i].plugin = currentplug; //worked
return true;

View file

@ -789,7 +789,7 @@ void PM_CategorizePosition (void)
//bsp objects marked as ladders mark regions to stand in to be classed as on a ladder.
cont = PM_ExtraBoxContents(pmove.origin);
#ifdef Q2BSPS
#ifdef Q3BSPS
//q3 has surfaceflag-based ladders
if (pmove.physents[0].model->fromgame == fg_quake3)
{

View file

@ -47,11 +47,6 @@ static char *strtolower(char *s)
void PF_Common_RegisterCvars(void)
{
static qboolean alreadydone;
if (alreadydone)
return;
alreadydone = true;
Cvar_Register (&pr_brokenfloatconvert, cvargroup_progs);
Cvar_Register (&pr_tempstringcount, cvargroup_progs);
Cvar_Register (&pr_tempstringsize, cvargroup_progs);

View file

@ -309,7 +309,6 @@ void QCBUILTIN PF_whichpack (progfuncs_t *prinst, struct globalvars_s *pr_global
void PF_fclose_progs (progfuncs_t *prinst);
int QCEditor (progfuncs_t *prinst, char *filename, int line, int nump, char **parms);
void PF_Common_RegisterCvars(void);

View file

@ -53,6 +53,22 @@ static int Q1_HullPointContents (hull_t *hull, int num, vec3_t p)
return num;
}
static int Q1_ModelPointContents (mnode_t *node, vec3_t p)
{
float d;
mplane_t *plane;
while(node->contents >= 0)
{
plane = node->plane;
if (plane->type < 3)
d = p[plane->type] - plane->dist;
else
d = DotProduct(plane->normal, p) - plane->dist;
node = node->children[d<0];
}
return node->contents;
}
#define DIST_EPSILON (0.03125)
@ -729,6 +745,10 @@ unsigned int Q1BSP_PointContents(model_t *model, vec3_t axis[3], vec3_t point)
transformed[2] = DotProduct(point, axis[2]);
return Q1BSP_HullPointContents(&model->hulls[0], transformed);
}
if (1)
{
return Q1BSP_TranslateContents(Q1_ModelPointContents(model->nodes, point));
}
return Q1BSP_HullPointContents(&model->hulls[0], point);
}

View file

@ -196,6 +196,8 @@ struct world_s
};
typedef struct world_s world_t;
void PF_Common_RegisterCvars(void);
#ifdef USEODE
void World_ODE_RemoveFromEntity(world_t *world, wedict_t *ed);
void World_ODE_RemoveJointFromEntity(world_t *world, wedict_t *ed);

View file

@ -66,6 +66,9 @@ qbyte sentinalkey;
#define TAGLESS 1
int zmemtotal;
int zmemdelta;
typedef struct memheader_s {
int size;
int tag;
@ -347,7 +350,14 @@ void *Z_Realloc(void *data, int newsize)
void *BZF_Malloc(int size) //BZ_Malloc but allowed to fail - like straight malloc.
{
return malloc(size);
void *mem;
mem = malloc(size);
if (mem)
{
zmemdelta += size;
zmemtotal += size;
}
return mem;
}
void *BZ_Malloc(int size) //Doesn't clear. The expectation is a large file, rather than sensative data structures.
@ -1206,13 +1216,13 @@ void Hunk_Print (qboolean all)
count = 0;
sum = 0;
totalblocks = 0;
h = (hunk_t *)hunk_base;
endlow = (hunk_t *)(hunk_base + hunk_low_used);
starthigh = (hunk_t *)(hunk_base + hunk_size - hunk_high_used);
endhigh = (hunk_t *)(hunk_base + hunk_size);
Con_Printf (" :%8i total hunk size\n", hunk_size);
Con_Printf (" :%12i total hunk size\n", hunk_size);
Con_Printf ("-------------------------\n");
while (1)
@ -1223,12 +1233,12 @@ void Hunk_Print (qboolean all)
if ( h == endlow )
{
Con_Printf ("-------------------------\n");
Con_Printf (" :%8i REMAINING\n", hunk_size - hunk_low_used - hunk_high_used);
Con_Printf (" :%8i USED\n", hunk_low_used + hunk_high_used);
Con_Printf (" : %12i REMAINING\n", hunk_size - hunk_low_used - hunk_high_used);
Con_Printf (" : %12i USED\n", hunk_low_used + hunk_high_used);
Con_Printf ("-------------------------\n");
h = starthigh;
}
//
// if totally done, break
//
@ -1268,8 +1278,8 @@ void Hunk_Print (qboolean all)
//
memcpy (name, h->name, 8);
if (all)
Con_Printf ("%8p :%8i %8s\n",h, h->size, name);
Con_Printf ("%8p :%12i %8s\n",h, h->size, name);
//
// print the total
//
@ -1277,7 +1287,7 @@ void Hunk_Print (qboolean all)
strncmp (h->name, next->name, 8) )
{
if (!all)
Con_Printf (" :%8i %8s (TOTAL)\n",sum, name);
Con_Printf (" :%12i %8s (TOTAL)\n",sum, name);
count = 0;
sum = 0;
}
@ -1748,6 +1758,12 @@ void Hunk_Print_f (void)
cacheused += cs->size;
}
Con_Printf("Cache: %iKB\n", cacheused/1024);
Con_Printf("Z Delta: %iKB\n", zmemdelta/1024); zmemdelta = 0;
Con_Printf("Z Total: %iKB\n", zmemtotal/1024);
//note: Zone memory isn't tracked reliably. we don't track the mem that is freed, so it'll just climb and climb
//we don't track reallocs either.
#if 0
{
zone_t *zone;

View file

@ -2049,6 +2049,7 @@ void D3DBE_SelectEntity(entity_t *ent)
/*Generates an optimised vbo for each of the given model's textures*/
void D3DBE_GenBrushModelVBO(model_t *mod)
{
#if 0
unsigned int maxvboverts;
unsigned int maxvboelements;
@ -2228,6 +2229,7 @@ void D3DBE_GenBrushModelVBO(model_t *mod)
IDirect3DIndexBuffer9_Unlock(ebuff);
IDirect3DVertexBuffer9_Unlock(vbuff);
}
#endif
}
/*Wipes a vbo*/
void D3DBE_ClearVBO(vbo_t *vbo)
@ -2438,10 +2440,7 @@ void D3DBE_SubmitBatch(batch_t *batch)
BE_RotateForEntity(batch->ent, batch->ent->model);
shaderstate.curtime = r_refdef.time - shaderstate.curentity->shaderTime;
}
if (batch->texture)
shaderstate.batchvbo = &batch->texture->vbo;
else
shaderstate.batchvbo = batch->vbo;
shaderstate.batchvbo = batch->vbo;
shaderstate.meshlist = batch->mesh + batch->firstmesh;
shaderstate.curshader = batch->shader;
shaderstate.curtexnums = batch->skin;

View file

@ -726,7 +726,6 @@ static qboolean D3D9_VID_Init(rendererstate_t *info, unsigned char *palette)
}
{
extern cvar_t v_contrast;
void GLV_Gamma_Callback(struct cvar_s *var, char *oldvalue);
Cvar_Hook(&v_gamma, GLV_Gamma_Callback);
Cvar_Hook(&v_contrast, GLV_Gamma_Callback);
@ -776,10 +775,6 @@ static void (D3D9_R_PreNewMap) (void)
r_viewleaf2 = NULL;
r_oldviewleaf2 = NULL;
}
static int (D3D9_R_LightPoint) (vec3_t point)
{
return 0;
}
static void (D3D9_VID_DeInit) (void)
{
@ -803,6 +798,9 @@ static void (D3D9_VID_DeInit) (void)
DestroyWindow(mainwindow);
mainwindow = NULL;
}
Cvar_Unhook(&v_gamma);
Cvar_Unhook(&v_contrast);
}
static void (D3D9_VID_SetPalette) (unsigned char *palette)
@ -1120,7 +1118,7 @@ static void (D3D9_Draw_Init) (void)
{
R2D_Init();
}
static void (D3D9_Draw_ReInit) (void)
static void (D3D9_Draw_Shutdown) (void)
{
}
@ -1220,7 +1218,6 @@ static void (D3D9_R_RenderView) (void)
void (D3D9_R_NewMap) (void);
void (D3D9_R_PreNewMap) (void);
int (D3D9_R_LightPoint) (vec3_t point);
void (D3D9_R_PushDlights) (void);
void (D3D9_R_AddStain) (vec3_t org, float red, float green, float blue, float radius);
@ -1251,7 +1248,7 @@ rendererinfo_t d3drendererinfo =
QR_DIRECT3D,
D3D9_Draw_Init,
D3D9_Draw_ReInit,
D3D9_Draw_Shutdown,
D3D9_LoadTexture,
D3D9_LoadTexture8Pal24,
@ -1268,7 +1265,6 @@ rendererinfo_t d3drendererinfo =
D3D9_R_NewMap,
D3D9_R_PreNewMap,
D3D9_R_LightPoint,
Surf_AddStain,
Surf_LessenStains,

View file

@ -25,6 +25,9 @@ EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nacl", "..\nacl\nacl.vcproj", "{4735677B-6D5A-4BE6-A945-CB32A7282F56}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xsv", "..\..\plugins\xsv\xsv.vcproj", "{873CCE24-3549-49D4-A4B4-653F91B1532A}"
ProjectSection(ProjectDependencies) = postProject
{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364} = {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -326,7 +329,6 @@ Global
{AA9D4AA8-2B98-42A8-9F63-B9E5A6221BB6}.Release|Win32.ActiveCfg = Release|Win32
{AA9D4AA8-2B98-42A8-9F63-B9E5A6221BB6}.Release|x64.ActiveCfg = Release|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.D3DDebug|Win32.ActiveCfg = Debug|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.D3DDebug|Win32.Build.0 = Debug|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.D3DDebug|x64.ActiveCfg = Debug|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.D3DRelease|Win32.ActiveCfg = Release|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.D3DRelease|Win32.Build.0 = Release|Win32
@ -338,13 +340,11 @@ Global
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.Debug|Win32.Build.0 = Debug|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.Debug|x64.ActiveCfg = Debug|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.GLDebug|Win32.ActiveCfg = Debug|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.GLDebug|Win32.Build.0 = Debug|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.GLDebug|x64.ActiveCfg = Debug|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.GLRelease|Win32.ActiveCfg = Release|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.GLRelease|Win32.Build.0 = Release|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.GLRelease|x64.ActiveCfg = Release|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.MDebug|Win32.ActiveCfg = Debug|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.MDebug|Win32.Build.0 = Debug|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.MDebug|x64.ActiveCfg = Debug|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.MinGLDebug|Win32.ActiveCfg = Debug|Win32
{4735677B-6D5A-4BE6-A945-CB32A7282F56}.MinGLDebug|Win32.Build.0 = Debug|Win32

View file

@ -1073,7 +1073,7 @@
FavorSizeOrSpeed="1"
OmitFramePointers="true"
AdditionalIncludeDirectories="../libs/speex;..\client;../libs/freetype2/include;../common;../server;../gl;../sw;../qclib;../libs;../libs/dxsdk9/include;../libs/dxsdk7/include"
PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;GLQUAKE;D3DQUAKE"
PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;GLQUAKE;D3DQUAKE;SWQUAKE"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
@ -1475,7 +1475,8 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../libs/speex;..\client;../libs/freetype2/include;../common;../server;../gl;../sw;../qclib;../libs;../libs/dxsdk9/include;../libs/dxsdk7/include"
PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS;GLQUAKE;D3DQUAKE"
PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS;GLQUAKE;D3DQUAKE;SWQUAKE;MULTITHREAD"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
FloatingPointModel="2"
UsePrecompiledHeader="2"
@ -27035,6 +27036,34 @@
>
</File>
</Filter>
<Filter
Name="sw"
>
<File
RelativePath="..\sw\sw.h"
>
</File>
<File
RelativePath="..\sw\sw_backend.c"
>
</File>
<File
RelativePath="..\sw\sw_image.c"
>
</File>
<File
RelativePath="..\sw\sw_rast.c"
>
</File>
<File
RelativePath="..\sw\sw_spans.h"
>
</File>
<File
RelativePath="..\sw\sw_vidwin.c"
>
</File>
</Filter>
</Filter>
<Filter
Name="libmad"

View file

@ -1854,7 +1854,7 @@ static void R_Sprite_GenerateBatch(entity_t *e, batch_t **batches, void (*drawfu
b->lightmap = -1;
b->surf_first = 0;
b->flags |= BEF_NODLIGHT|BEF_NOSHADOWS;
b->vbo = 0;
b->vbo = NULL;
b->next = batches[sort];
batches[sort] = b;
}

View file

@ -87,6 +87,7 @@ static const char PCFPASS_SHADER[] = "\
extern cvar_t r_glsl_offsetmapping, r_noportals;
static void BE_SendPassBlendDepthMask(unsigned int sbits);
void GLBE_RenderToTexture(texid_t sourcecol, texid_t sourcedepth, texid_t destcol, qboolean usedepth);
void GLBE_SubmitBatch(batch_t *batch);
struct {
@ -119,6 +120,9 @@ struct {
texid_t tex_sourcecol; /*this is used by $sourcecolour tgen*/
texid_t tex_sourcedepth;
int fbo_depthless;
int fbo_reflection;
texid_t tex_reflection;
texid_t tex_refraction;
qboolean force2d;
int currenttmu;
@ -1007,6 +1011,12 @@ static void Shader_BindTextureForPass(int tmu, const shaderpass_t *pass)
case T_GEN_SOURCEDEPTH:
t = shaderstate.tex_sourcedepth;
break;
case T_GEN_REFLECTION:
t = shaderstate.tex_reflection;
break;
case T_GEN_REFRACTION:
t = shaderstate.tex_refraction;
break;
}
GL_LazyBind(tmu, GL_TEXTURE_2D, t);
}
@ -1886,6 +1896,36 @@ static void deformgen(const deformv_t *deformv, int cnt, vecV_t *src, vecV_t *ds
}
}
static void GenerateVertexBlends(const shader_t *shader)
{
int i, m;
mesh_t *meshlist;
vecV_t *ov, *iv1, *iv2;
float w1, w2;
for (m = 0; m < shaderstate.meshcount; m++)
{
meshlist = shaderstate.meshes[m];
ov = vertexarray+meshlist->vbofirstvert;
iv1 = meshlist->xyz_array;
iv2 = meshlist->xyz2_array;
w1 = meshlist->xyz_blendw[0];
w2 = meshlist->xyz_blendw[1];
for (i = 0; i < meshlist->numvertexes; i++)
{
ov[i][0] = iv1[i][0]*w1 + iv2[i][0]*w2;
ov[i][1] = iv1[i][1]*w1 + iv2[i][1]*w2;
ov[i][2] = iv1[i][2]*w1 + iv2[i][2]*w2;
}
for (i = 0; i < shader->numdeforms; i++)
{
deformgen(&shader->deforms[i], meshlist->numvertexes, vertexarray+meshlist->vbofirstvert, vertexarray+meshlist->vbofirstvert, meshlist);
}
}
shaderstate.pendingvertexpointer = vertexarray;
shaderstate.pendingvertexvbo = 0;
}
static void GenerateVertexDeforms(const shader_t *shader)
{
int i, m;
@ -2074,6 +2114,7 @@ static void GenerateColourMods(const shaderpass_t *pass)
alphagen(pass, meshlist->numvertexes, meshlist->colors4f_array, coloursarray + meshlist->vbofirstvert, meshlist);
}
shaderstate.colourarraytype = GL_FLOAT;
shaderstate.pendingcolourvbo = 0;
shaderstate.pendingcolourpointer = coloursarray;
}
@ -3063,14 +3104,6 @@ static void DrawMeshes(void)
RQuantAdd(RQUANT_ENTBATCHES, 1);
}
if (shaderstate.curshader->numdeforms)
GenerateVertexDeforms(shaderstate.curshader);
else
{
shaderstate.pendingvertexpointer = shaderstate.sourcevbo->coord.gl.addr;
shaderstate.pendingvertexvbo = shaderstate.sourcevbo->coord.gl.vbo;
}
#ifndef FORCESTATE
if (shaderstate.curcull != (shaderstate.curshader->flags & (SHADER_CULL_FRONT|SHADER_CULL_BACK)))
#endif
@ -3092,6 +3125,16 @@ static void DrawMeshes(void)
}
}
if (shaderstate.sourcevbo->coord2.gl.addr)
GenerateVertexBlends(shaderstate.curshader);
else if (shaderstate.curshader->numdeforms)
GenerateVertexDeforms(shaderstate.curshader);
else
{
shaderstate.pendingvertexpointer = shaderstate.sourcevbo->coord.gl.addr;
shaderstate.pendingvertexvbo = shaderstate.sourcevbo->coord.gl.vbo;
}
BE_PolyOffset(shaderstate.flags & BEF_PUSHDEPTH);
switch(shaderstate.mode)
{
@ -3341,7 +3384,7 @@ void GLBE_SubmitBatch(batch_t *batch)
}
}
static void BE_SubmitMeshesPortals(batch_t **worldlist, batch_t *dynamiclist)
static void GLBE_SubmitMeshesPortals(batch_t **worldlist, batch_t *dynamiclist)
{
batch_t *batch, *old;
int i;
@ -3362,12 +3405,12 @@ static void BE_SubmitMeshesPortals(batch_t **worldlist, batch_t *dynamiclist)
/*draw already-drawn portals as depth-only, to ensure that their contents are not harmed*/
BE_SelectMode(BEM_DEPTHONLY);
GLBE_SelectMode(BEM_DEPTHONLY);
for (old = worldlist[SHADER_SORT_PORTAL]; old && old != batch; old = old->next)
{
if (old->meshes == old->firstmesh)
continue;
BE_SubmitBatch(old);
GLBE_SubmitBatch(old);
}
if (!old)
{
@ -3375,10 +3418,10 @@ static void BE_SubmitMeshesPortals(batch_t **worldlist, batch_t *dynamiclist)
{
if (old->meshes == old->firstmesh)
continue;
BE_SubmitBatch(old);
GLBE_SubmitBatch(old);
}
}
BE_SelectMode(BEM_STANDARD);
GLBE_SelectMode(BEM_STANDARD);
GLR_DrawPortal(batch, worldlist);
@ -3391,7 +3434,7 @@ static void BE_SubmitMeshesPortals(batch_t **worldlist, batch_t *dynamiclist)
}
}
static void BE_SubmitMeshesSortList(batch_t *sortlist)
static void GLBE_SubmitMeshesSortList(batch_t *sortlist)
{
batch_t *batch;
for (batch = sortlist; batch; batch = batch->next)
@ -3430,7 +3473,51 @@ static void BE_SubmitMeshesSortList(batch_t *sortlist)
continue;
}
BE_SubmitBatch(batch);
if (batch->shader->flags & (SHADER_HASREFLECT | SHADER_HASREFRACT))
{
//these two flags require rendering some view as an fbo
if (r_refdef.recurse)
return;
if (batch->shader->flags & SHADER_HASREFLECT)
{
if (!shaderstate.tex_reflection.num)
{
shaderstate.tex_reflection = GL_AllocNewTexture("***tex_reflection***", vid.pixelwidth, vid.pixelheight);
GL_MTBind(0, GL_TEXTURE_2D, shaderstate.tex_reflection);
qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, vid.pixelwidth, vid.pixelheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
GLBE_RenderToTexture(r_nulltex, r_nulltex, shaderstate.tex_reflection, true);
GL_ForceDepthWritable();
qglClear(GL_DEPTH_BUFFER_BIT);
GLR_DrawPortal(batch, cl.worldmodel->batches);
GLBE_RenderToTexture(r_nulltex, r_nulltex, r_nulltex, false);
}
if (batch->shader->flags & SHADER_HASREFRACT)
{
if (!shaderstate.tex_refraction.num)
{
shaderstate.tex_refraction = GL_AllocNewTexture("***tex_refraction***", vid.pixelwidth, vid.pixelheight);
GL_MTBind(0, GL_TEXTURE_2D, shaderstate.tex_refraction);
qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, vid.pixelwidth, vid.pixelheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
GLBE_RenderToTexture(r_nulltex, r_nulltex, shaderstate.tex_refraction, true);
GL_ForceDepthWritable();
qglClear(GL_DEPTH_BUFFER_BIT);
GLR_DrawPortal(batch, cl.worldmodel->batches);
GLBE_RenderToTexture(r_nulltex, r_nulltex, r_nulltex, false);
}
}
GLBE_SubmitBatch(batch);
}
}
@ -3444,11 +3531,11 @@ void GLBE_SubmitMeshes (qboolean drawworld, batch_t **blist, int start, int stop
if (drawworld)
{
if (i == SHADER_SORT_PORTAL && !r_noportals.ival && !r_refdef.recurse)
BE_SubmitMeshesPortals(model->batches, blist[i]);
GLBE_SubmitMeshesPortals(model->batches, blist[i]);
BE_SubmitMeshesSortList(model->batches[i]);
GLBE_SubmitMeshesSortList(model->batches[i]);
}
BE_SubmitMeshesSortList(blist[i]);
GLBE_SubmitMeshesSortList(blist[i]);
}
}
@ -3526,7 +3613,7 @@ void GLBE_BaseEntTextures(void)
}
#endif
void GLBE_RenderToTexture(texid_t sourcecol, texid_t sourcedepth, texid_t destcol, texid_t destdepth, qboolean usedepth)
void GLBE_RenderToTexture(texid_t sourcecol, texid_t sourcedepth, texid_t destcol, qboolean usedepth)
{
shaderstate.tex_sourcecol = sourcecol;
shaderstate.tex_sourcedepth = sourcedepth;
@ -3534,16 +3621,40 @@ void GLBE_RenderToTexture(texid_t sourcecol, texid_t sourcedepth, texid_t destco
qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
else
{
if (!shaderstate.fbo_depthless)
if (usedepth)
{
qglGenFramebuffersEXT(1, &shaderstate.fbo_depthless);
qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, shaderstate.fbo_depthless);
if (!shaderstate.fbo_diffuse)
{
int drb;
qglDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
qglReadBuffer(GL_NONE);
qglGenFramebuffersEXT(1, &shaderstate.fbo_diffuse);
qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, shaderstate.fbo_diffuse);
//create an unnamed depth buffer
qglGenRenderbuffersEXT(1, &drb);
qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, drb);
qglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24_ARB, vid.pixelwidth, vid.pixelheight);
qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, drb);
qglDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
qglReadBuffer(GL_NONE);
}
else
qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, shaderstate.fbo_diffuse);
}
else
qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, shaderstate.fbo_depthless);
{
if (!shaderstate.fbo_depthless)
{
qglGenFramebuffersEXT(1, &shaderstate.fbo_depthless);
qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, shaderstate.fbo_depthless);
qglDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
qglReadBuffer(GL_NONE);
}
else
qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, shaderstate.fbo_depthless);
}
qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, destcol.num, 0);
}

View file

@ -58,7 +58,7 @@ static int texwidth[MAXLEVELS], texheight[MAXLEVELS];
void GLBE_RenderToTexture(texid_t sourcecol, texid_t sourcedepth, texid_t destcol, texid_t destdepth, qboolean usedepth);
void GLBE_RenderToTexture(texid_t sourcecol, texid_t sourcedepth, texid_t destcol, qboolean usedepth);
void R_BloomRegister(void)
{
@ -188,13 +188,13 @@ void R_BloomBlend (void)
qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_refdef.pxrect.x, r_refdef.pxrect.y - r_refdef.pxrect.height, r_refdef.pxrect.width, r_refdef.pxrect.height);
/*filter the screen into a downscaled image*/
GLBE_RenderToTexture(scrtex, r_nulltex, pingtex[0][0], r_nulltex, false);
GLBE_RenderToTexture(scrtex, r_nulltex, pingtex[0][0], false);
qglViewport (0, 0, texwidth[0], texheight[0]);
R2D_ScalePic(0, vid.height, vid.width, -(int)vid.height, bloomfilter);
/*and downscale that multiple times*/
for (i = 1; i < MAXLEVELS; i++)
{
GLBE_RenderToTexture(pingtex[0][i-1], r_nulltex, pingtex[0][i], r_nulltex, false);
GLBE_RenderToTexture(pingtex[0][i-1], r_nulltex, pingtex[0][i], false);
qglViewport (0, 0, texwidth[i], texheight[i]);
R2D_ScalePic(0, vid.height, vid.width, -(int)vid.height, bloomrescale);
}
@ -205,7 +205,7 @@ void R_BloomBlend (void)
/*must be 1.2th of a pixel*/
r_worldentity.glowmod[0] = 1.2 / texwidth[i];
r_worldentity.glowmod[1] = 0;
GLBE_RenderToTexture(pingtex[0][i], r_nulltex, pingtex[1][i], r_nulltex, false);
GLBE_RenderToTexture(pingtex[0][i], r_nulltex, pingtex[1][i], false);
qglViewport (0, 0, texwidth[i], texheight[i]);
R2D_ScalePic(0, vid.height, vid.width, -(int)vid.height, bloomblur);
}
@ -213,7 +213,7 @@ void R_BloomBlend (void)
{
r_worldentity.glowmod[0] = 0;
r_worldentity.glowmod[1] = 1.2 / texheight[i];
GLBE_RenderToTexture(pingtex[1][i], r_nulltex, pingtex[0][i], r_nulltex, false);
GLBE_RenderToTexture(pingtex[1][i], r_nulltex, pingtex[0][i], false);
qglViewport (0, 0, texwidth[i], texheight[i]);
R2D_ScalePic(0, vid.height, vid.width, -(int)vid.height, bloomblur);
}
@ -221,7 +221,7 @@ void R_BloomBlend (void)
GL_Set2D(false);
/*combine them onto the screen*/
GLBE_RenderToTexture(scrtex, r_nulltex, r_nulltex, r_nulltex, false);
GLBE_RenderToTexture(scrtex, r_nulltex, r_nulltex, false);
R2D_ScalePic(r_refdef.vrect.x, r_refdef.vrect.y + r_refdef.vrect.height, r_refdef.vrect.width, -r_refdef.vrect.height, bloomfinal);
}
void R_InitBloomTextures(void)

View file

@ -490,7 +490,7 @@ TRACE(("dbg: GLDraw_ReInit: Allocating upload buffers\n"));
TRACE(("dbg: GLDraw_ReInit: PPL_LoadSpecularFragmentProgram\n"));
GL_InitSceneProcessingShaders();
Cmd_AddRemCommand ("r_imagelist", GLDraw_ImageList_f);
Cmd_AddCommand ("r_imagelist", GLDraw_ImageList_f);
}
void GLDraw_DeInit (void)
@ -1397,7 +1397,7 @@ void GL_Upload24BGR (char *name, qbyte *framedata, int inwidth, int inheight, un
outheight = 512;
if (outwidth*outheight > sizeofuploadmemorybufferintermediate/4)
Sys_Error("MediaGL_ShowFrameBGR_24_Flip: image too big (%i*%i)", inwidth, inheight);
Sys_Error("GL_Upload24BGR: image too big (%i*%i)", inwidth, inheight);
for (y=0 ; y<outheight ; y++)
{

View file

@ -288,7 +288,6 @@ void RMod_Think (void)
VFS_WRITE(f, "QLIT\1\0\0\0", 8);
VFS_WRITE(f, lightmodel->lightdata, numlightdata*3);
VFS_CLOSE(f);
COM_FlushFSCache();
}
else
Con_Printf("Unable to write \"%s\"\n", filename);
@ -326,7 +325,6 @@ Mod_ClearAll
void RMod_ClearAll (void)
{
int i;
int t;
model_t *mod;
#ifdef RUNTIMELIGHTING
@ -354,12 +352,6 @@ void RMod_ClearAll (void)
if (mod->type == mod_brush)
{
Surf_Clear(mod);
for (t = 0; t < mod->numtextures; t++)
{
if (!mod->textures[t])
continue;
BE_ClearVBO(&mod->textures[t]->vbo);
}
}
#ifdef TERRAIN
if (mod->type == mod_heightmap)
@ -386,8 +378,8 @@ void RMod_Init (void)
mod_numknown = 0;
Q1BSP_Init();
Cmd_AddRemCommand("mod_texturelist", RMod_TextureList_f);
Cmd_AddRemCommand("mod_usetexture", RMod_BlockTextureColour_f);
Cmd_AddCommand("mod_texturelist", RMod_TextureList_f);
Cmd_AddCommand("mod_usetexture", RMod_BlockTextureColour_f);
}
void RMod_Shutdown (void)
@ -1066,7 +1058,6 @@ Mod_LoadTextures
*/
qboolean RMod_LoadTextures (lump_t *l)
{
extern int gl_bumpmappingpossible;
int i, j, pixels, num, max, altmax;
miptex_t *mt;
texture_t *tx, *tx2;
@ -1220,13 +1211,10 @@ TRACE(("dbg: RMod_LoadTextures: inittexturedescs\n"));
tn.bump = r_nulltex;
if (r_loadbumpmapping)
{
if (r_loadbumpmapping)
{
snprintf(altname, sizeof(altname)-1, "%s_norm", mt->name);
tn.bump = R_LoadReplacementTexture(altname, loadname, IF_NOGAMMA|IF_SUBDIRONLY|IF_MIPCAP);
if (!TEXVALID(tn.bump))
tn.bump = R_LoadReplacementTexture(altname, "bmodels", IF_NOGAMMA|IF_MIPCAP);
}
snprintf(altname, sizeof(altname)-1, "%s_norm", mt->name);
tn.bump = R_LoadReplacementTexture(altname, loadname, IF_NOGAMMA|IF_SUBDIRONLY|IF_MIPCAP);
if (!TEXVALID(tn.bump))
tn.bump = R_LoadReplacementTexture(altname, "bmodels", IF_NOGAMMA|IF_MIPCAP);
if (!TEXVALID(tn.bump))
{
if (gl_load24bit.value)
@ -1240,7 +1228,7 @@ TRACE(("dbg: RMod_LoadTextures: inittexturedescs\n"));
snprintf(altname, sizeof(altname)-1, "%s_bump", mt->name);
}
/* if (!TEXVALID(tn.bump) && loadmodel->fromgame != fg_halflife)
if (!TEXVALID(tn.bump) && loadmodel->fromgame != fg_halflife)// && gl_bump_fallbacks.ival)
{
//no mip levels here, would be absurd.
base = (qbyte *)(mt+1); //convert to greyscale.
@ -1249,7 +1237,7 @@ TRACE(("dbg: RMod_LoadTextures: inittexturedescs\n"));
tn.bump = R_LoadTexture8BumpPal(altname, tx->width, tx->height, base, true); //normalise it and then bump it.
}
*/
//don't do any complex quake 8bit -> glossmap. It would likly look a little ugly...
if (gl_specular.value && gl_load24bit.value)
{
@ -1372,7 +1360,6 @@ TRACE(("dbg: RMod_LoadTextures: inittexturedescs\n"));
void RMod_NowLoadExternal(void)
{
extern int gl_bumpmappingpossible;
int i, width, height;
qboolean alphaed;
texture_t *tx;
@ -3322,12 +3309,6 @@ qboolean RMod_LoadBrushModel (model_t *mod, void *buffer)
mod->numframes = 2; // regular and alternate animation
/*FIXME: move mesh_t and lightmap allocation out of r_surf
for (i=0 ; i<mod->numsurfaces ; i++)
{
Surf_BuildSurfaceDisplayList (mod, mod->surfaces + i);
}
*/
//
// set up the submodels (FIXME: this is confusing)

View file

@ -113,6 +113,7 @@ typedef struct batch_s
/*caller-use, not interpreted by backend*/
union
{
unsigned int shadowbatch; //a unique index to accelerate shadowmesh generation (dlights, yay!)
struct
{
unsigned int surf_first;
@ -291,6 +292,8 @@ typedef struct vbo_s
unsigned int vbobones;
float *bones;
unsigned int numbones;
struct vbo_s *next;
} vbo_t;
void GL_SelectVBO(int vbo);
void GL_SelectEBO(int vbo);
@ -300,13 +303,9 @@ typedef struct texture_s
char name[64];
unsigned width, height;
qbyte pixbytes;
qbyte alphaed; //gl_blend needed on this surface.
struct shader_s *shader;
int wtexno;
vbo_t vbo;
int anim_total; // total tenths in sequence ( 0 = no)
int anim_min, anim_max; // time for this frame min <=time< max
@ -949,6 +948,12 @@ typedef struct model_s
q3lightgridinfo_t *lightgrid;
char *entities;
struct {
texture_t *tex;
vbo_t *vbo;
} *shadowbatches;
int numshadowbatches;
vbo_t *vbos;
void *terrain;
batch_t *batches[SHADER_SORT_COUNT];

View file

@ -817,9 +817,12 @@ void R_LoadRTLights(void)
dl->coronascale = coronascale;
dl->die = 0;
dl->flags = flags;
dl->lightcolourscales[0] = ambientscale;
dl->lightcolourscales[1] = diffusescale;
dl->lightcolourscales[2] = specularscale;
if (ambientscale || diffusescale || specularscale)
{
dl->lightcolourscales[0] = ambientscale;
dl->lightcolourscales[1] = diffusescale;
dl->lightcolourscales[2] = specularscale;
}
AngleVectors(angles, dl->axis[0], dl->axis[1], dl->axis[2]);
Q_strncpyz(dl->cubemapname, cubename, sizeof(dl->cubemapname));
@ -1153,7 +1156,7 @@ int GLRecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end)
int GLR_LightPoint (vec3_t p)
int R_LightPoint (vec3_t p)
{
vec3_t end;
int r;

View file

@ -69,7 +69,7 @@ cvar_t gl_affinemodels = SCVAR("gl_affinemodels","0");
cvar_t gl_reporttjunctions = SCVAR("gl_reporttjunctions","0");
cvar_t gl_finish = SCVAR("gl_finish","0");
cvar_t gl_dither = SCVAR("gl_dither", "1");
cvar_t r_postprocshader = CVARD("r_postprocshader", "", "Specifies a shader to use as a post-processing shader");
extern cvar_t r_postprocshader;
extern cvar_t gl_screenangle;
@ -733,6 +733,10 @@ void GLR_DrawPortal(batch_t *batch, batch_t **blist)
qglClipPlane(GL_CLIP_PLANE0, glplane);
qglEnable(GL_CLIP_PLANE0);
}
frustum[4].normal[0] = plane.normal[0];
frustum[4].normal[1] = plane.normal[1];
frustum[4].normal[2] = plane.normal[2];
frustum[4].dist = plane.dist + 0.01;
R_RenderScene();
if (qglClipPlane)
qglDisable(GL_CLIP_PLANE0);

View file

@ -450,11 +450,8 @@ void GLR_DeInit (void)
Cvar_Unhook(&vid_conautoscale);
Cvar_Unhook(&vid_conheight);
Cvar_Unhook(&vid_conwidth);
Cvar_Unhook(&r_wallcolour);
Cvar_Unhook(&r_floorcolour);
Cvar_Unhook(&r_walltexture);
Cvar_Unhook(&r_floortexture);
Cvar_Unhook(&r_fastskycolour);
Cvar_Unhook(&r_drawflat);
Cvar_Unhook(&v_gamma);
Cvar_Unhook(&v_contrast);
@ -466,13 +463,10 @@ void GLR_DeInit (void)
void GLR_Init (void)
{
Cmd_AddRemCommand ("timerefresh", GLR_TimeRefresh_f);
Cmd_AddCommand ("timerefresh", GLR_TimeRefresh_f);
// Cmd_AddRemCommand ("makewad", R_MakeTexWad_f);
// Cmd_AddCommand ("makewad", R_MakeTexWad_f);
// Cvar_Hook(&r_floorcolour, GLR_Floorcolour_Callback);
// Cvar_Hook(&r_fastskycolour, GLR_Fastskycolour_Callback);
// Cvar_Hook(&r_wallcolour, GLR_Wallcolour_Callback);
// Cvar_Hook(&r_floortexture, GLR_Floortexture_Callback);
// Cvar_Hook(&r_walltexture, GLR_Walltexture_Callback);
// Cvar_Hook(&r_drawflat, GLR_Drawflat_Callback);

View file

@ -131,12 +131,11 @@ void *allocbuf(char **p, int elements, int elementsize)
return ret;
}
void GLBE_GenBrushModelVBO(model_t *mod)
void GLBE_GenBatchVBOs(vbo_t **vbochain, batch_t *firstbatch, batch_t *stopbatch)
{
unsigned int maxvboverts;
unsigned int maxvboelements;
unsigned int t;
unsigned int i;
unsigned int v;
unsigned int vcount, ecount;
@ -155,7 +154,166 @@ void GLBE_GenBrushModelVBO(model_t *mod)
vec3_t *tvector;
vec4_t *colours;
index_t *indicies;
batch_t *batch;
vbo = Z_Malloc(sizeof(*vbo));
maxvboverts = 0;
maxvboelements = 0;
meshes = 0;
for(batch = firstbatch; batch != stopbatch; batch = batch->next)
{
for (i=0 ; i<batch->meshes ; i++)
{
m = batch->mesh[i];
meshes++;
maxvboelements += m->numindexes;
maxvboverts += m->numvertexes;
}
}
if (maxvboverts > MAX_INDICIES)
Sys_Error("Building a vbo with too many verticies\n");
vcount = 0;
ecount = 0;
pervertsize = sizeof(vecV_t)+ //coord
sizeof(vec2_t)+ //tex
sizeof(vec2_t)+ //lm
sizeof(vec3_t)+ //normal
sizeof(vec3_t)+ //sdir
sizeof(vec3_t)+ //tdir
sizeof(vec4_t); //colours
vbo->vertdata = BZ_Malloc((maxvboverts+1)*pervertsize + (maxvboelements+1)*sizeof(index_t));
p = vbo->vertdata;
vbo->coord.gl.addr = allocbuf(&p, maxvboverts, sizeof(vecV_t));
vbo->texcoord.gl.addr = allocbuf(&p, maxvboverts, sizeof(vec2_t));
vbo->lmcoord.gl.addr = allocbuf(&p, maxvboverts, sizeof(vec2_t));
vbo->normals.gl.addr = allocbuf(&p, maxvboverts, sizeof(vec3_t));
vbo->svector.gl.addr = allocbuf(&p, maxvboverts, sizeof(vec3_t));
vbo->tvector.gl.addr = allocbuf(&p, maxvboverts, sizeof(vec3_t));
vbo->colours.gl.addr = allocbuf(&p, maxvboverts, sizeof(vec4_t));
vbo->indicies.gl.addr = allocbuf(&p, maxvboelements, sizeof(index_t));
coord = vbo->coord.gl.addr;
texcoord = vbo->texcoord.gl.addr;
lmcoord = vbo->lmcoord.gl.addr;
normals = vbo->normals.gl.addr;
svector = vbo->svector.gl.addr;
tvector = vbo->tvector.gl.addr;
colours = vbo->colours.gl.addr;
indicies = vbo->indicies.gl.addr;
//vbo->meshcount = meshes;
//vbo->meshlist = BZ_Malloc(meshes*sizeof(*vbo->meshlist));
meshes = 0;
for(batch = firstbatch; batch != stopbatch; batch = batch->next)
{
batch->vbo = vbo;
for (i=0 ; i<batch->meshes ; i++)
{
m = batch->mesh[i];
// surf->mark = &vbo->meshlist[meshes++];
// *surf->mark = NULL;
m->vbofirstvert = vcount;
m->vbofirstelement = ecount;
for (v = 0; v < m->numindexes; v++)
indicies[ecount++] = vcount + m->indexes[v];
for (v = 0; v < m->numvertexes; v++)
{
coord[vcount+v][0] = m->xyz_array[v][0];
coord[vcount+v][1] = m->xyz_array[v][1];
coord[vcount+v][2] = m->xyz_array[v][2];
if (m->st_array)
{
texcoord[vcount+v][0] = m->st_array[v][0];
texcoord[vcount+v][1] = m->st_array[v][1];
}
if (m->lmst_array)
{
lmcoord[vcount+v][0] = m->lmst_array[v][0];
lmcoord[vcount+v][1] = m->lmst_array[v][1];
}
if (m->normals_array)
{
normals[vcount+v][0] = m->normals_array[v][0];
normals[vcount+v][1] = m->normals_array[v][1];
normals[vcount+v][2] = m->normals_array[v][2];
}
if (m->snormals_array)
{
svector[vcount+v][0] = m->snormals_array[v][0];
svector[vcount+v][1] = m->snormals_array[v][1];
svector[vcount+v][2] = m->snormals_array[v][2];
}
if (m->tnormals_array)
{
tvector[vcount+v][0] = m->tnormals_array[v][0];
tvector[vcount+v][1] = m->tnormals_array[v][1];
tvector[vcount+v][2] = m->tnormals_array[v][2];
}
if (m->colors4f_array)
{
colours[vcount+v][0] = m->colors4f_array[v][0];
colours[vcount+v][1] = m->colors4f_array[v][1];
colours[vcount+v][2] = m->colors4f_array[v][2];
colours[vcount+v][3] = m->colors4f_array[v][3];
}
}
vcount += v;
}
}
if (GL_BuildVBO(vbo, vbo->vertdata, vcount*pervertsize, indicies, ecount*sizeof(index_t), 0))
{
BZ_Free(vbo->vertdata);
vbo->vertdata = NULL;
}
vbo->next = *vbochain;
*vbochain = vbo;
}
void GLBE_GenBrushModelVBO(model_t *mod)
{
unsigned int vcount;
batch_t *batch, *fbatch;
int sortid;
fbatch = NULL;
vcount = 0;
for (sortid = 0; sortid < SHADER_SORT_COUNT; sortid++)
{
if (!mod->batches[sortid])
continue;
for (fbatch = batch = mod->batches[sortid]; batch != NULL; batch = batch->next)
{
//firstmesh got reused as the number of verticies in each batch
if (vcount + batch->firstmesh > MAX_INDICIES)
{
GLBE_GenBatchVBOs(&mod->vbos, fbatch, batch);
fbatch = batch;
vcount = 0;
}
vcount += batch->firstmesh;
}
GLBE_GenBatchVBOs(&mod->vbos, fbatch, batch);
}
#if 0
if (!mod->numsurfaces)
return;
@ -292,6 +450,7 @@ void GLBE_GenBrushModelVBO(model_t *mod)
vbo->vertdata = NULL;
}
}
#endif
}
void GLBE_UploadAllLightmaps(void)

View file

@ -1040,91 +1040,6 @@ struct sbuiltin_s
"}\n"
"#endif\n"
},
{QR_OPENGL, 110, "default2d",
"#ifdef VERTEX_SHADER\n"
"attribute vec2 v_texcoord;\n"
"attribute vec4 v_colour;\n"
"varying vec2 tc;\n"
"varying vec4 vc;\n"
"void main ()\n"
"{\n"
" tc = v_texcoord;\n"
" vc = v_colour;\n"
" gl_Position = ftetransform();\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform sampler2D s_t0;\n"
"in vec2 tc;\n"
"varying vec4 vc;\n"
"void main ()\n"
"{\n"
" gl_FragColor = texture2D(s_t0, tc) * vc;\n"
"}\n"
"#endif\n"
},
{QR_OPENGL, 110, "defaultsprite",
"!!permu FOG\n"
"#include \"sys/fog.h\"\n"
"#ifdef VERTEX_SHADER\n"
"attribute vec2 v_texcoord;\n"
"attribute vec4 v_colour;\n"
"varying vec2 tc;\n"
"varying vec4 vc;\n"
"void main ()\n"
"{\n"
" tc = v_texcoord;\n"
" vc = v_colour;\n"
" gl_Position = ftetransform();\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform sampler2D s_t0;\n"
"varying vec2 tc;\n"
"varying vec4 vc;\n"
"uniform vec4 e_colourident;\n"
"void main ()\n"
"{\n"
" gl_FragColor = fog4blend(texture2D(s_t0, tc) * vc * e_colourident);\n"
"}\n"
"#endif\n"
},
{QR_OPENGL, 110, "defaultadditivesprite",
"!!permu FOG\n"
"#include \"sys/fog.h\"\n"
"#ifdef VERTEX_SHADER\n"
"attribute vec2 v_texcoord;\n"
"attribute vec4 v_colour;\n"
"varying vec2 tc;\n"
"varying vec4 vc;\n"
"void main ()\n"
"{\n"
" tc = v_texcoord;\n"
" vc = v_colour;\n"
" gl_Position = ftetransform();\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform sampler2D s_t0;\n"
"varying vec2 tc;\n"
"varying vec4 vc;\n"
"uniform vec4 e_colourident;\n"
"void main ()\n"
"{\n"
" gl_FragColor = fog4additive(texture2D(s_t0, tc) * vc * e_colourident);\n"
"}\n"
"#endif\n"
},
/*draws a wall, with lightmap.*/
{QR_OPENGL/*ES*/, 100, "defaultwall",
"#ifdef VERTEX_SHADER\n"
@ -1155,76 +1070,6 @@ struct sbuiltin_s
"}\n"
"#endif\n"
},
{QR_OPENGL, 110, "defaultwall",
"!!permu OFFSETMAPPING\n"
"!!permu FULLBRIGHT\n"
"!!permu FOG\n"
"!!cvarf r_glsl_offsetmapping_scale\n"
"#include \"sys/fog.h\"\n"
"#if defined(OFFSETMAPPING)\n"
"varying vec3 eyevector;\n"
"#endif\n"
"#ifdef VERTEX_SHADER\n"
"attribute vec2 v_texcoord;\n"
"attribute vec2 v_lmcoord;\n"
"varying vec2 tc, lm;\n"
"#if defined(OFFSETMAPPING)\n"
"uniform vec3 e_eyepos;\n"
"attribute vec3 v_normal;\n"
"attribute vec3 v_svector;\n"
"attribute vec3 v_tvector;\n"
"#endif\n"
"void main ()\n"
"{\n"
"#if defined(OFFSETMAPPING)\n"
"vec3 eyeminusvertex = e_eyepos - v_position.xyz;\n"
"eyevector.x = dot(eyeminusvertex, v_svector.xyz);\n"
"eyevector.y = -dot(eyeminusvertex, v_tvector.xyz);\n"
"eyevector.z = dot(eyeminusvertex, v_normal.xyz);\n"
"#endif\n"
" tc = v_texcoord;\n"
" lm = v_lmcoord;\n"
" gl_Position = ftetransform();\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform sampler2D s_t0;\n" /*tex_diffuse*/
"uniform sampler2D s_t1;\n" /*tex_lightmap*/
"#ifdef OFFSETMAPPING\n"
"uniform sampler2D s_t2;\n" /*tex_normalmap*/
"#endif\n"
//"uniform sampler2D s_t3;\n" /*tex_deluxmap*/
"#ifdef FULLBRIGHT\n"
"uniform sampler2D s_t4;\n" /*tex_fullbright*/
"#endif\n"
"varying vec2 tc, lm;\n"
"uniform vec4 e_lmscale;\n"
"uniform vec4 e_colourident;\n"
"#ifdef OFFSETMAPPING\n"
"#include \"sys/offsetmapping.h\"\n"
"#endif\n"
"void main ()\n"
"{\n"
"#ifdef OFFSETMAPPING\n"
"vec2 tcoffsetmap = offsetmap(s_t2, tc, eyevector);\n"
"#define tc tcoffsetmap\n"
"#endif\n"
" gl_FragColor = texture2D(s_t0, tc) * texture2D(s_t1, lm) * e_lmscale;\n"
"#ifdef FULLBRIGHT\n"
" gl_FragColor.rgb += texture2D(s_t4, tc).rgb;\n"
"#endif\n"
"gl_FragColor = gl_FragColor * e_colourident;\n"
"#ifdef FOG\n"
"gl_FragColor = fog4(gl_FragColor);\n"
"#endif\n"
"}\n"
"#endif\n"
},
{QR_OPENGL, 100, "drawflat_wall",
"!!cvarv r_floorcolor\n"
"!!cvarv r_wallcolor\n"
@ -1247,38 +1092,6 @@ struct sbuiltin_s
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform sampler2D s_t0;\n" /*tex_lightmap*/
"varying vec2 lm;\n"
"void main ()\n"
"{\n"
" gl_FragColor = fog4(col * texture2D(s_t0, lm));\n"
"}\n"
"#endif\n"
},
{QR_OPENGL, 110, "drawflat_wall",
"!!cvarv r_floorcolor\n"
"!!cvarv r_wallcolor\n"
"!!permu FOG\n"
"#include \"sys/fog.h\"\n"
"varying vec4 col;\n"
"#ifdef VERTEX_SHADER\n"
"attribute vec3 v_normal;\n"
"attribute vec2 v_lmcoord;\n"
"varying vec2 lm;\n"
"uniform vec3 cvar_r_wallcolor;\n"
"uniform vec3 cvar_r_floorcolor;\n"
"uniform vec4 e_lmscale;\n"
"void main ()\n"
"{\n"
" col = vec4(e_lmscale.rgb/255.0 * ((v_normal.z < 0.73)?cvar_r_wallcolor:cvar_r_floorcolor), e_lmscale.a);\n"
" lm = v_lmcoord;\n"
" gl_Position = ftetransform();\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform sampler2D s_t0;\n" /*tex_lightmap*/
"varying vec2 lm;\n"
@ -1318,146 +1131,6 @@ struct sbuiltin_s
"}\n"
"#endif\n"
},
{QR_OPENGL, 110, "defaultwarp",
"!!cvarf r_wateralpha\n"
"!!permu FOG\n"
"#include \"sys/fog.h\"\n"
"varying vec2 tc;\n"
"#ifdef VERTEX_SHADER\n"
"attribute vec2 v_texcoord;\n"
"void main ()\n"
"{\n"
" tc = v_texcoord.st;\n"
" gl_Position = ftetransform();\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform sampler2D s_t0;\n"
"uniform float e_time;\n"
"uniform float cvar_r_wateralpha;\n"
"void main ()\n"
"{\n"
" vec2 ntc;\n"
" ntc.s = tc.s + sin(tc.t+e_time)*0.125;\n"
" ntc.t = tc.t + sin(tc.s+e_time)*0.125;\n"
" vec3 ts = vec3(texture2D(s_t0, ntc));\n"
" gl_FragColor = fog4(vec4(ts, cvar_r_wateralpha));\n"
"}\n"
"#endif\n"
},
{QR_OPENGL, 110, "underwaterwarp",
/*
inputs:
texcoords: edge points
coords: vertex coords (duh)
time
ampscale (cvar = r_waterwarp)
use ifs instead of an edge map?
*/
"!!cvarf r_waterwarp\n"
"#ifdef VERTEX_SHADER\n"
"attribute vec2 v_texcoord;\n"
"varying vec2 v_stc;\n"
"varying vec2 v_warp;\n"
"varying vec2 v_edge;\n"
"uniform float e_time;\n"
"void main ()\n"
"{\n"
"gl_Position = ftetransform();\n"
"v_stc = (1.0+(gl_Position.xy / gl_Position.w))/2.0;\n"
"v_warp.s = e_time * 0.25 + v_texcoord.s;\n"
"v_warp.t = e_time * 0.25 + v_texcoord.t;\n"
"v_edge = v_texcoord.xy;\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"varying vec2 v_stc;\n"
"varying vec2 v_warp;\n"
"varying vec2 v_edge;\n"
"uniform sampler2D s_t0;/*$currentrender*/\n"
"uniform sampler2D s_t1;/*warp image*/\n"
"uniform sampler2D s_t2;/*edge image*/\n"
"uniform vec3 e_rendertexturescale;\n"
"uniform float cvar_r_waterwarp;\n"
"void main ()\n"
"{\n"
"float amptemp;\n"
"vec3 edge;\n"
"edge = texture2D( s_t2, v_edge ).rgb;\n"
"amptemp = (0.010 / 0.625) * cvar_r_waterwarp * edge.x;\n"
"vec3 offset;\n"
"offset = texture2D( s_t1, v_warp ).rgb;\n"
"offset.x = (offset.x - 0.5) * 2.0;\n"
"offset.y = (offset.y - 0.5) * 2.0;\n"
"vec2 temp;\n"
"temp.x = v_stc.x + offset.x * amptemp;\n"
"temp.y = v_stc.y + offset.y * amptemp;\n"
"gl_FragColor = texture2D( s_t0, temp*e_rendertexturescale.st );\n"
"}\n"
"#endif\n"
},
{QR_OPENGL, 110, "postproc_panorama",
"!!cvarf ffov\n"
"#ifdef VERTEX_SHADER\n"
"attribute vec2 v_texcoord;\n"
"varying vec2 texcoord;\n"
"void main()\n"
"{\n"
"texcoord = v_texcoord.xy;\n"
"gl_Position = ftetransform();\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform samplerCube s_t0;\n"
"varying vec2 texcoord;\n"
"uniform float cvar_ffov;\n"
"void main()\n"
"{\n"
"vec3 tc; \n"
"float ang; \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"
},
{QR_OPENGL, 110, "postproc_fisheye",
"!!cvarf ffov\n"
"#ifdef VERTEX_SHADER\n"
"attribute vec2 v_texcoord;\n"
"varying vec2 texcoord;\n"
"void main()\n"
"{\n"
"texcoord = v_texcoord.xy;\n"
"gl_Position = ftetransform();\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform samplerCube s_t0;\n"
"varying vec2 texcoord;\n"
"uniform float cvar_ffov;\n"
"void main()\n"
"{\n"
"vec3 tc; \n"
"vec2 d; \n"
"vec2 ang; \n"
"d = texcoord; \n"
"ang.x = sqrt(d.x*d.x+d.y*d.y)*radians(cvar_ffov); \n"
"ang.y = -atan(d.y, d.x); \n"
"tc.x = sin(ang.x) * cos(ang.y); \n"
"tc.y = sin(ang.x) * sin(ang.y); \n"
"tc.z = cos(ang.x); \n"
"gl_FragColor = textureCube(s_t0, tc);\n"
"}\n"
"#endif\n"
},
/*defautsky projects the texture in order to match q1 skies, along with two separate layers scrolling at separate speeds*/
{QR_OPENGL/*ES*/, 100, "defaultsky",
"#ifdef VERTEX_SHADER\n"
@ -1498,43 +1171,6 @@ struct sbuiltin_s
"}\n"
"#endif\n"
},
{QR_OPENGL, 110, "defaultsky",
"#ifdef VERTEX_SHADER\n"
"varying vec3 pos;\n"
"void main ()\n"
"{\n"
" pos = v_position.xyz;\n"
" gl_Position = ftetransform();\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform float e_time;\n"
"uniform vec3 e_eyepos;\n"
"varying vec3 pos;\n"
"uniform sampler2D s_t0;\n"
"uniform sampler2D s_t1;\n"
"void main ()\n"
"{\n"
" vec2 tccoord;\n"
" vec3 dir = pos - e_eyepos;\n"
" dir.z *= 3.0;\n"
" dir.xy /= 0.5*length(dir);\n"
" tccoord = (dir.xy + e_time*0.03125);\n"
" vec3 solid = vec3(texture2D(s_t0, tccoord));\n"
" tccoord = (dir.xy + e_time*0.0625);\n"
" vec4 clouds = texture2D(s_t1, tccoord);\n"
" gl_FragColor.rgb = (solid.rgb*(1.0-clouds.a)) + (clouds.a*clouds.rgb);\n"
"}\n"
"#endif\n"
},
/*draws a model. there's lots of extra stuff for light shading calcs and upper/lower textures*/
{QR_OPENGL/*ES*/, 100, "defaultskin",
"!!permu FULLBRIGHT\n"
@ -1598,560 +1234,6 @@ struct sbuiltin_s
"}\n"
"#endif\n"
},
{QR_OPENGL, 110, "defaultskin",
"!!permu FULLBRIGHT\n"
"!!permu UPPERLOWER\n"
"!!permu FRAMEBLEND\n"
"!!permu SKELETAL\n"
"!!permu FOG\n"
"varying vec2 tc;\n"
"varying vec3 light;\n"
"#ifdef VERTEX_SHADER\n"
"#include \"sys/skeletal.h\"\n"
"attribute vec2 v_texcoord;\n"
"uniform vec3 e_light_dir;\n"
"uniform vec3 e_light_mul;\n"
"uniform vec3 e_light_ambient;\n"
"void main ()\n"
"{\n"
" vec3 n;\n"
" gl_Position = skeletaltransform_n(n);\n"
" light = e_light_ambient + (dot(n,e_light_dir)*e_light_mul);\n"
" tc = v_texcoord;\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"#include \"sys/fog.h\"\n"
"uniform sampler2D s_t0;\n" /*tex_diffuse*/
"#ifdef LOWER\n"
"uniform sampler2D s_t1;\n" /*tex_lower*/
"uniform vec3 e_lowercolour;\n"
"#endif\n"
"#ifdef UPPER\n"
"uniform sampler2D s_t2;\n" /*tex_upper*/
"uniform vec3 e_uppercolour;\n"
"#endif\n"
"#ifdef FULLBRIGHT\n"
"uniform sampler2D s_t3;\n" /*tex_fullbright*/
"#endif\n"
"uniform vec4 e_colourident;\n"
"void main ()\n"
"{\n"
" vec4 col, sp;\n"
" col = texture2D(s_t0, tc);\n"
"#ifdef UPPER\n"
" vec4 uc = texture2D(s_t2, tc);\n"
" col.rgb = mix(col.rgb, uc.rgb*e_uppercolour, uc.a);\n"
"#endif\n"
"#ifdef LOWER\n"
" vec4 lc = texture2D(s_t1, tc);\n"
" col.rgb = mix(col.rgb, lc.rgb*e_lowercolour, lc.a);\n"
"#endif\n"
" col.rgb *= light;\n"
"#ifdef FULLBRIGHT\n"
" vec4 fb = texture2D(s_t3, tc);\n"
" col.rgb = mix(col.rgb, fb.rgb, fb.a);\n"
"#endif\n"
" gl_FragColor = fog4(col * e_colourident);\n"
"}\n"
"#endif\n"
},
{QR_OPENGL, 110, "lpp_depthnorm",
"!!permu BUMP\n"
"!!permu SKELETAL\n"
"varying vec3 norm, tang, bitang;\n"
"#if defined(BUMP)\n"
"varying vec2 tc;\n"
"#endif\n"
"#ifdef VERTEX_SHADER\n"
"#include \"sys/skeletal.h\"\n"
"attribute vec2 v_texcoord;\n"
"void main()\n"
"{\n"
"#if defined(BUMP)\n"
"gl_Position = skeletaltransform_nst(norm, tang, bitang);\n"
"tc = v_texcoord;\n"
"#else\n"
"gl_Position = skeletaltransform_n(norm);\n"
"#endif\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"#if defined(BUMP)\n"
"uniform sampler2D s_t0;\n"
"#endif\n"
"void main()\n"
"{\n"
"vec3 onorm;\n"
"#if defined(BUMP)\n"
/*transform by the normalmap*/
"vec3 bm = 2.0*texture2D(s_t0, tc).xyz - 1.0;\n"
"onorm = normalize(bm.x * tang + bm.y * bitang + bm.z * norm);\n"
"#else\n"
"onorm = norm;\n"
"#endif\n"
"gl_FragColor = vec4(onorm.xyz, gl_FragCoord.z / gl_FragCoord.w);\n"
"}\n"
"#endif\n"
},
{QR_OPENGL, 110, "lpp_light",
"varying vec4 tf;\n"
"#ifdef VERTEX_SHADER\n"
"void main()\n"
"{\n"
"tf = ftetransform(); gl_Position = tf;\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform sampler2D s_t0;\n"
"uniform vec3 l_lightposition;\n"
"uniform mat4 m_invviewprojection;\n"
"uniform vec3 l_lightcolour;\n"
"uniform float l_lightradius;\n"
"vec3 calcLightWorldPos(vec2 screenPos, float depth)\n"
"{\n"
"vec4 pos;\n"
"pos.x = screenPos.x;\n"
"pos.y = screenPos.y;\n"
"pos.z = depth;\n"
"pos.w = 1.0;\n"
"pos = m_invviewprojection * pos;\n"
"return pos.xyz / pos.w;\n"
"}\n"
"void main ()\n"
"{\n"
"vec3 lightColour = l_lightcolour.rgb;\n"
"float lightIntensity = 1.0;\n"
"float lightAttenuation = l_lightradius;\n" // fixme: just use the light radius for now, use better near/far att math separately once working
"float radiusFar = l_lightradius;\n"
"float radiusNear = l_lightradius*0.5;\n"
"vec2 fc;\n"
"fc = tf.xy / tf.w;\n"
"vec4 data = texture2D(s_t0, (1.0 + fc) / 2.0);\n"
"float depth = data.a;\n"
"vec3 norm = data.xyz;\n"
/* calc where the wall that generated this sample came from */
"vec3 worldPos = calcLightWorldPos(fc, depth);\n"
/*calc diffuse lighting term*/
"vec3 lightDir = l_lightposition - worldPos;\n"
"float zdiff = 1.0 - clamp(length(lightDir) / lightAttenuation, 0.0, 1.0);\n"
"float atten = (radiusFar * zdiff) / (radiusFar - radiusNear);\n"
"atten = pow(atten, 2.0);\n"
"lightDir = normalize(lightDir);\n"
"float nDotL = dot(norm, lightDir) * atten;\n"
"float lightDiffuse = max(0.0, nDotL);\n"
/*calc specular term*/
// todo: specular term in its own buffer for full coloured specular
"gl_FragColor = vec4(lightDiffuse * (lightColour * lightIntensity), 1.0);\n"
// gl_FragColor = vec4(normalize(lightDir), 0.0);
"}\n"
"#endif\n"
},
{QR_OPENGL, 110, "lpp_wall",
"varying vec2 tc, lm;\n"
"varying vec4 tf;\n"
"#ifdef VERTEX_SHADER\n"
"attribute vec2 v_texcoord;\n"
"attribute vec2 v_lmcoord;\n"
"void main ()\n"
"{\n"
"tc = v_texcoord;\n"
"lm = v_lmcoord;\n"
"gl_Position = tf = ftetransform();\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform sampler2D s_t0;\n" /*lpp lighting*/
"uniform sampler2D s_t1;\n" /*tex_diffuse*/
"uniform sampler2D s_t2;\n" /*tex_lightmap*/
//"uniform sampler2D s_t3;\n" /*tex_normalmap*/
//"uniform sampler2D s_t4;\n" /*tex_deluxmap*/
//"uniform sampler2D s_t5;\n" /*tex_fullbright*/
"uniform vec4 e_lmscale;\n"
"void main ()\n"
"{\n"
//"gl_FragColor = texture2D(s_t0, tc) * texture2D(s_t1, lm) * e_lmscale;\n"
"vec2 nst;\n"
"nst = tf.xy / tf.w;\n"
"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*lmscale;\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"
"gl_FragColor = vec4((diff + lmsamp) * c.xyz, 1.0);\n" // + 0.6 * spec, 1.0);
"}\n"
"#endif\n"
},
{QR_OPENGL, 110, "colourtint",
"varying vec4 tf;\n"
"#ifdef VERTEX_SHADER\n"
"void main ()\n"
"{\n"
"gl_Position = tf = vec4(v_position.xy,-1.0, 1.0);\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform sampler2D s_t0;\n"
"uniform sampler3D s_t1;\n"
"void main()\n"
"{\n"
"vec2 fc;\n"
"fc = tf.xy / tf.w;\n"
"vec3 raw = texture2D(s_t0, (1.0 + fc) / 2.0).rgb;\n"
//scale+bias the sample to not clamp out at the edges
"#define LUTSIZE 16.0\n"
"vec3 scale = vec3((LUTSIZE-1.0)/LUTSIZE);\n"
"vec3 bias = vec3(1.0/(2.0*LUTSIZE));\n"
"gl_FragColor = texture3D(s_t1, raw * scale + bias);\n"
"}\n"
"#endif\n"
},
{QR_OPENGL, 110, "crepuscular_rays",
/*yoinked from http://fabiensanglard.net/lightScattering/index.php*/
"!!cvarf crep_decay\n"
"!!cvarf crep_density\n"
"!!cvarf crep_weight\n"
"varying vec2 tc;\n"
"#ifdef VERTEX_SHADER\n"
"attribute vec2 v_texcoord;\n"
"void main ()\n"
"{\n"
"tc = v_texcoord;\n"
"gl_Position = v_position;\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"const float crep_decay = 0.94;\n"
"const float crep_density = 0.5;\n"
"const float crep_weight = 0.2;\n"
"uniform vec3 l_lightcolour;\n"
"uniform vec3 l_lightscreen;\n"
"uniform sampler2D s_t0;\n"
"const int NUM_SAMPLES = 100;\n"
"void main()\n"
"{\n"
// "gl_FragColor = texture2D(s_t0, tc.st);\n"
"vec2 deltaTextCoord = vec2( tc.st - l_lightscreen.xy );\n"
"vec2 textCoo = tc.st;\n"
"deltaTextCoord *= 1.0 / float(NUM_SAMPLES) * crep_density;\n"
"float illuminationDecay = 1.0;\n"
"for(int i=0; i < NUM_SAMPLES ; i++)\n"
"{\n"
"textCoo -= deltaTextCoord;\n"
"vec4 sample = texture2D(s_t0, textCoo);\n"
"sample *= illuminationDecay * crep_weight;\n"
"gl_FragColor += sample;\n"
"illuminationDecay *= crep_decay;\n"
"}\n"
"gl_FragColor *= vec4(l_lightcolour, 1.0);\n"
"}\n"
"#endif\n"
},
{QR_OPENGL, 110, "crepuscular_opaque",
"#ifdef VERTEX_SHADER\n"
"void main ()\n"
"{\n"
"gl_Position = ftetransform();\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"void main()\n"
"{\n"
"gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);\n"
"}\n"
"#endif\n"
},
{QR_OPENGL, 110, "crepuscular_sky",
"#ifdef VERTEX_SHADER\n"
"varying vec3 pos;\n"
"void main ()\n"
"{\n"
" pos = v_position.xyz;\n"
" gl_Position = ftetransform();\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform float e_time;\n"
"uniform vec3 e_eyepos;\n"
"varying vec3 pos;\n"
"uniform sampler2D s_t0;\n"
"uniform sampler2D s_t1;\n"
"void main ()\n"
"{\n"
" vec2 tccoord;\n"
" vec3 dir = pos - e_eyepos;\n"
" dir.z *= 3.0;\n"
" dir.xy /= 0.5*length(dir);\n"
" tccoord = (dir.xy + e_time*0.03125);\n"
" vec3 solid = vec3(texture2D(s_t0, tccoord));\n"
" tccoord = (dir.xy + e_time*0.0625);\n"
" vec4 clouds = texture2D(s_t1, tccoord);\n"
" gl_FragColor.rgb = (solid.rgb*(1.0-clouds.a)) + (clouds.a*clouds.rgb);\n"
"}\n"
"#endif\n"
},
{QR_OPENGL, 110, "rtlight",
/*
texture units:
s0=diffuse, s1=normal, s2=specular, s3=shadowmap
custom modifiers:
PCF(shadowmap)
CUBE(projected cubemap)
*/
"!!permu BUMP\n"
"!!permu SPECULAR\n"
"!!permu OFFSETMAPPING\n"
"!!permu SKELETAL\n"
"!!permu FOG\n"
"!!cvarf r_glsl_offsetmapping_scale\n"
"varying vec2 tcbase;\n"
"varying vec3 lightvector;\n"
"#if defined(SPECULAR) || defined(OFFSETMAPPING)\n"
"varying vec3 eyevector;\n"
"#endif\n"
"#if defined(PCF) || defined(CUBE)\n"
"varying vec4 vshadowcoord;\n"
"uniform mat4 l_projmatrix;\n"
"#endif\n"
"#ifdef VERTEX_SHADER\n"
"#include \"sys/skeletal.h\"\n"
"uniform vec3 l_lightposition;\n"
"attribute vec2 v_texcoord;\n"
"#if defined(SPECULAR) || defined(OFFSETMAPPING)\n"
"uniform vec3 e_eyepos;\n"
"#endif\n"
"void main ()\n"
"{\n"
"vec3 n, s, t, w;\n"
"gl_Position = skeletaltransform_wnst(w,n,s,t);\n"
"tcbase = v_texcoord; //pass the texture coords straight through\n"
"vec3 lightminusvertex = l_lightposition - w.xyz;\n"
"lightvector.x = dot(lightminusvertex, s.xyz);\n"
"lightvector.y = dot(lightminusvertex, t.xyz);\n"
"lightvector.z = dot(lightminusvertex, n.xyz);\n"
"#if defined(SPECULAR)||defined(OFFSETMAPPING)\n"
"vec3 eyeminusvertex = e_eyepos - w.xyz;\n"
"eyevector.x = dot(eyeminusvertex, s.xyz);\n"
"eyevector.y = -dot(eyeminusvertex, t.xyz);\n"
"eyevector.z = dot(eyeminusvertex, n.xyz);\n"
"#endif\n"
"#if defined(PCF) || defined(SPOT) || defined(PROJECTION) || defined(CUBE)\n"
"vshadowcoord = l_projmatrix*vec4(w.xyz, 1.0);\n"
"#endif\n"
"}\n"
"#endif\n"
/*this is full 4*4 PCF, with an added attempt at prenumbra*/
/*the offset consts are 1/(imagesize*2) */
#define PCF16P(f) "\
float xPixelOffset = (1.0+shadowcoord.b/l_lightradius)/texx;\
float yPixelOffset = (1.0+shadowcoord.b/l_lightradius)/texy;\
float s = 0.0;\n\
s += "f"Proj(s_t7, shadowcoord + vec4(-1.5 * xPixelOffset * shadowcoord.w, -1.5 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\
s += "f"Proj(s_t7, shadowcoord + vec4(-1.5 * xPixelOffset * shadowcoord.w, -0.5 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\
s += "f"Proj(s_t7, shadowcoord + vec4(-1.5 * xPixelOffset * shadowcoord.w, 0.5 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\
s += "f"Proj(s_t7, shadowcoord + vec4(-1.5 * xPixelOffset * shadowcoord.w, 1.1 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\
\
s += "f"Proj(s_t7, shadowcoord + vec4(-0.5 * xPixelOffset * shadowcoord.w, -1.5 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\
s += "f"Proj(s_t7, shadowcoord + vec4(-0.5 * xPixelOffset * shadowcoord.w, -0.5 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\
s += "f"Proj(s_t7, shadowcoord + vec4(-0.5 * xPixelOffset * shadowcoord.w, 0.5 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\
s += "f"Proj(s_t7, shadowcoord + vec4(-0.5 * xPixelOffset * shadowcoord.w, 1.1 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\
\
s += "f"Proj(s_t7, shadowcoord + vec4(0.5 * xPixelOffset * shadowcoord.w, -1.5 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\
s += "f"Proj(s_t7, shadowcoord + vec4(0.5 * xPixelOffset * shadowcoord.w, -0.5 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\
s += "f"Proj(s_t7, shadowcoord + vec4(0.5 * xPixelOffset * shadowcoord.w, 0.5 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\
s += "f"Proj(s_t7, shadowcoord + vec4(0.5 * xPixelOffset * shadowcoord.w, 1.1 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\
\
s += "f"Proj(s_t7, shadowcoord + vec4(1.5 * xPixelOffset * shadowcoord.w, -1.5 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\
s += "f"Proj(s_t7, shadowcoord + vec4(1.5 * xPixelOffset * shadowcoord.w, -0.5 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\
s += "f"Proj(s_t7, shadowcoord + vec4(1.5 * xPixelOffset * shadowcoord.w, 0.5 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\
s += "f"Proj(s_t7, shadowcoord + vec4(1.5 * xPixelOffset * shadowcoord.w, 1.1 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\
\
colorscale *= s/5.0;\n\
"
/*this is pcf 3*3*/
/*the offset consts are 1/(imagesize*2) */
#define PCF9(f) "\
const float xPixelOffset = 1.0/texx;\
const float yPixelOffset = 1.0/texy;\
float s = 0.0;\n\
s += "f"Proj(s_t7, shadowcoord + vec4(-1.0 * xPixelOffset * shadowcoord.w, -1.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\
s += "f"Proj(s_t7, shadowcoord + vec4(-1.0 * xPixelOffset * shadowcoord.w, 0.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\
s += "f"Proj(s_t7, shadowcoord + vec4(-1.0 * xPixelOffset * shadowcoord.w, 1.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\
\
s += "f"Proj(s_t7, shadowcoord + vec4(0.0 * xPixelOffset * shadowcoord.w, -1.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\
s += "f"Proj(s_t7, shadowcoord + vec4(0.0 * xPixelOffset * shadowcoord.w, 0.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\
s += "f"Proj(s_t7, shadowcoord + vec4(0.0 * xPixelOffset * shadowcoord.w, 1.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\
\
s += "f"Proj(s_t7, shadowcoord + vec4(1.0 * xPixelOffset * shadowcoord.w, -1.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\
s += "f"Proj(s_t7, shadowcoord + vec4(1.0 * xPixelOffset * shadowcoord.w, 0.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\
s += "f"Proj(s_t7, shadowcoord + vec4(1.0 * xPixelOffset * shadowcoord.w, 1.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\
colorscale *= s/9.0;\n\
"
/*this is a lazy form of pcf. take 5 samples in an x*/
/*the offset consts are 1/(imagesize*2) */
#define PCF5(f) "\
float xPixelOffset = 1.0/texx;\
float yPixelOffset = 1.0/texy;\
float s = 0.0;\n\
s += "f"Proj(s_t7, shadowcoord + vec4(-1.0 * xPixelOffset * shadowcoord.w, -1.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\
s += "f"Proj(s_t7, shadowcoord + vec4(-1.0 * xPixelOffset * shadowcoord.w, 1.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\
s += "f"Proj(s_t7, shadowcoord + vec4(0.0 * xPixelOffset * shadowcoord.w, 0.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\
s += "f"Proj(s_t7, shadowcoord + vec4(1.0 * xPixelOffset * shadowcoord.w, -1.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\
s += "f"Proj(s_t7, shadowcoord + vec4(1.0 * xPixelOffset * shadowcoord.w, 1.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\
colorscale *= s/5.0;\n\
"
/*this is unfiltered*/
#define PCF1(f) "\
colorscale *= "f"Proj(shadowmap, shadowcoord).r;\n"
"#ifdef FRAGMENT_SHADER\n"
"#include \"sys/fog.h\"\n"
"uniform sampler2D s_t0;\n"/*base texture*/
"#if defined(BUMP) || defined(SPECULAR) || defined(OFFSETMAPPING)\n"
"uniform sampler2D s_t1;\n"/*normalmap/height texture*/
"#endif\n"
"#ifdef SPECULAR\n"
"uniform sampler2D s_t2;\n"/*specularmap texture*/
"#endif\n"
"#ifdef CUBE\n"
"uniform samplerCube s_t3;\n"/*projected texture*/
"#endif\n"
"#ifdef PCF\n"
"#ifdef CUBE\n"
"uniform samplerCubeShadow s_t7;\n"
"#else\n"
"uniform sampler2DShadow s_t7;\n"
"#endif\n"
"#endif\n"
"uniform float l_lightradius;\n"
"uniform vec3 l_lightcolour;\n"
"uniform vec3 l_lightcolourscale;\n"
"#ifdef OFFSETMAPPING\n"
"#include \"sys/offsetmapping.h\"\n"
"#endif\n"
"void main ()\n"
"{\n"
"#ifdef OFFSETMAPPING\n"
"vec2 tcoffsetmap = offsetmap(s_t1, tcbase, eyevector);\n"
"#define tcbase tcoffsetmap\n"
"#endif\n"
"vec3 bases = vec3(texture2D(s_t0, tcbase));\n"
"#if defined(BUMP) || defined(SPECULAR)\n"
"vec3 bumps = vec3(texture2D(s_t1, tcbase)) - 0.5;\n"
"#endif\n"
"#ifdef SPECULAR\n"
"vec4 specs = texture2D(s_t2, tcbase);\n"
"#endif\n"
"vec3 nl = normalize(lightvector);\n"
"float colorscale = max(1.0 - dot(lightvector, lightvector)/(l_lightradius*l_lightradius), 0.0);\n"
"vec3 diff;\n"
"#ifdef BUMP\n"
"diff = bases * (l_lightcolourscale.x + l_lightcolourscale.y * max(dot(2.0*bumps, nl), 0.0));\n"
"#else\n"
"diff = bases * (l_lightcolourscale.x + l_lightcolourscale.y * max(dot(vec3(0.0, 0.0, 1.0), nl), 0.0));\n"
"#endif\n"
"#ifdef SPECULAR\n"
"vec3 halfdir = normalize(lightvector - normalize(eyevector));\n"
"float spec = pow(max(dot(halfdir, bumps), 0.0), 1.0 + 32.0 * specs.a);\n"
"diff += spec * specs.rgb * l_lightcolourscale.z;\n"
"#endif\n"
"#ifdef CUBE\n"
"diff *= textureCube(s_t3, vshadowcoord.xyz).rgb;\n"
"#endif\n"
"#ifdef PCF\n"
"#if defined(SPOT)\n"
"const float texx = 512.0;\n"
"const float texy = 512.0;\n"
"vec4 shadowcoord = vshadowcoord;\n"
"#else\n"
"const float texx = 512.0;\n"
"const float texy = 512.0;\n"
"vec4 shadowcoord;\n"
"shadowcoord.zw = vshadowcoord.zw;\n"
"shadowcoord.xy = vshadowcoord.xy;\n"
"#endif\n"
"#ifdef CUBE\n"
PCF9("shadowCube") /*valid are 1,5,9*/
"#else\n"
PCF9("shadow2D") /*valid are 1,5,9*/
"#endif\n"
"#endif\n"
"#if defined(SPOT)\n"
/*Actually, this isn't correct*/
"if (shadowcoord.w < 0.0) discard;\n"
"vec2 spot = ((shadowcoord.st)/shadowcoord.w - 0.5)*2.0;colorscale*=1.0-(dot(spot,spot));\n"
"#endif\n"
"#if defined(PROJECTION)\n"
"l_lightcolour *= texture2d(s_t3, shadowcoord);\n"
"#endif\n"
"gl_FragColor.rgb = fog3additive(diff*colorscale*l_lightcolour);\n"
"}\n"
"#endif\n"
},
#endif
#ifdef D3DQUAKE
{QR_DIRECT3D, 9, "rtlight",
@ -3104,6 +2186,18 @@ static qboolean ShaderPass_MapGen (shader_t *shader, shaderpass_t *pass, char *t
pass->texgen = T_GEN_SOURCEDEPTH;
pass->tcgen = TC_GEN_BASE; //FIXME: moo!
}
else if (!Q_stricmp (tname, "$reflection"))
{
shader->flags |= SHADER_HASREFLECT;
pass->texgen = T_GEN_REFLECTION;
pass->tcgen = TC_GEN_BASE; //FIXME: moo!
}
else if (!Q_stricmp (tname, "$refraction"))
{
shader->flags |= SHADER_HASREFRACT;
pass->texgen = T_GEN_REFRACTION;
pass->tcgen = TC_GEN_BASE; //FIXME: moo!
}
else
return false;
return true;
@ -5212,7 +4306,7 @@ void Shader_DefaultBSPQ1(char *shortname, shader_t *s, const void *args)
"{\n"
"map $diffuse\n"
"tcgen base\n"
"alphamask\n"
"alphamask\n"
"}\n"
"if $lightmap\n"
"[\n"

View file

@ -66,8 +66,10 @@ void Sh_Shutdown(void)
typedef struct {
unsigned int count;
unsigned int max;
texture_t *tex;
vbo_t *vbo;
mesh_t **s;
} shadowmeshsurfs_t;
} shadowmeshbatch_t;
typedef struct shadowmesh_s {
qboolean surfonly;
unsigned int numindicies;
@ -79,8 +81,8 @@ typedef struct shadowmesh_s {
vecV_t *verts;
//we also have a list of all the surfaces that this light lights.
unsigned int numsurftextures;
shadowmeshsurfs_t *litsurfs;
unsigned int numbatches;
shadowmeshbatch_t *batches;
unsigned int leafbytes;
unsigned char *litleaves;
@ -216,17 +218,17 @@ static void SHM_Shadow_Cache_Surface(msurface_t *surf)
{
int i;
i = surf->texinfo->texture->wtexno;
i = surf->sbatch->shadowbatch;
if (i < 0)
return;
if (sh_shmesh->litsurfs[i].count == sh_shmesh->litsurfs[i].max)
if (sh_shmesh->batches[i].count == sh_shmesh->batches[i].max)
{
sh_shmesh->litsurfs[i].max += 64;
sh_shmesh->litsurfs[i].s = BZ_Realloc(sh_shmesh->litsurfs[i].s, sizeof(void*)*(sh_shmesh->litsurfs[i].max));
sh_shmesh->batches[i].max += 64;
sh_shmesh->batches[i].s = BZ_Realloc(sh_shmesh->batches[i].s, sizeof(void*)*(sh_shmesh->batches[i].max));
}
sh_shmesh->litsurfs[i].s[sh_shmesh->litsurfs[i].count] = surf->mesh;
sh_shmesh->litsurfs[i].count++;
sh_shmesh->batches[i].s[sh_shmesh->batches[i].count] = surf->mesh;
sh_shmesh->batches[i].count++;
}
static void SHM_Shadow_Cache_Leaf(mleaf_t *leaf)
@ -240,9 +242,9 @@ static void SHM_Shadow_Cache_Leaf(mleaf_t *leaf)
void SH_FreeShadowMesh(shadowmesh_t *sm)
{
unsigned int i;
for (i = 0; i < sm->numsurftextures; i++)
Z_Free(sm->litsurfs[i].s);
Z_Free(sm->litsurfs);
for (i = 0; i < sm->numbatches; i++)
Z_Free(sm->batches[i].s);
Z_Free(sm->batches);
Z_Free(sm->indicies);
Z_Free(sm->verts);
@ -270,6 +272,46 @@ void SH_FreeShadowMesh(shadowmesh_t *sm)
Z_Free(sm);
}
static void SH_CalcShadowBatches(model_t *mod)
{
int s;
batch_t *b;
batch_t *l = NULL;
int sb;
l = NULL;
for (s = 0; s < SHADER_SORT_COUNT; s++)
{
for (b = mod->batches[s]; b; b = b->next)
{
if (!l || l->vbo != b->vbo || l->texture != b->texture)
{
b->shadowbatch = mod->numshadowbatches++;
l = b;
}
else
b->shadowbatch = l->shadowbatch;
}
}
l = NULL;
sb = 0;
mod->shadowbatches = BZ_Malloc(sizeof(*mod->shadowbatches)*mod->numshadowbatches);
for (s = 0; s < SHADER_SORT_COUNT; s++)
{
for (b = mod->batches[s]; b; b = b->next)
{
if (!l || l->vbo != b->vbo || l->texture != b->texture)
{
mod->shadowbatches[sb].tex = b->texture;
mod->shadowbatches[sb].vbo = b->vbo;
sb++;
l = b;
}
}
}
}
static void SHM_BeginShadowMesh(dlight_t *dl, qboolean surfonly)
{
unsigned int i;
@ -314,21 +356,26 @@ static void SHM_BeginShadowMesh(dlight_t *dl, qboolean surfonly)
sh_shmesh->numindicies = 0;
sh_shmesh->surfonly = surfonly;
if (sh_shmesh->numsurftextures != cl.worldmodel->numtextures)
if (!cl.worldmodel->numshadowbatches)
{
if (sh_shmesh->litsurfs)
{
for (i = 0; i < sh_shmesh->numsurftextures; i++)
Z_Free(sh_shmesh->litsurfs[i].s);
Z_Free(sh_shmesh->litsurfs);
}
sh_shmesh->litsurfs = Z_Malloc(sizeof(shadowmeshsurfs_t)*cl.worldmodel->numtextures);
sh_shmesh->numsurftextures=cl.worldmodel->numtextures;
SH_CalcShadowBatches(cl.worldmodel);
}
else
if (sh_shmesh->numbatches != cl.worldmodel->numshadowbatches)
{
for (i = 0; i < sh_shmesh->numsurftextures; i++)
sh_shmesh->litsurfs[i].count = 0;
if (sh_shmesh->batches)
{
for (i = 0; i < sh_shmesh->numbatches; i++)
Z_Free(sh_shmesh->batches[i].s);
Z_Free(sh_shmesh->batches);
}
sh_shmesh->batches = Z_Malloc(sizeof(shadowmeshbatch_t)*cl.worldmodel->numshadowbatches);
sh_shmesh->numbatches=cl.worldmodel->numshadowbatches;
}
for (i = 0; i < sh_shmesh->numbatches; i++)
{
sh_shmesh->batches[i].count = 0;
}
}
static struct shadowmesh_s *SHM_FinishShadowMesh(dlight_t *dl)
@ -1040,7 +1087,7 @@ static void SHM_ComposeVolume_Soup(vecV_t *points, int numpoints, index_t *idx,
/*call this function after generating litsurfs meshes*/
static void SHM_ComposeVolume_BruteForce(dlight_t *dl)
{
shadowmeshsurfs_t *sms;
shadowmeshbatch_t *sms;
unsigned int tno;
unsigned int sno;
int i, e;
@ -1050,9 +1097,9 @@ static void SHM_ComposeVolume_BruteForce(dlight_t *dl)
cv.numpoints = 0;
cv.numtris = 0;
for (tno = 0; tno < sh_shmesh->numsurftextures; tno++)
for (tno = 0; tno < sh_shmesh->numbatches; tno++)
{
sms = &sh_shmesh->litsurfs[tno];
sms = &sh_shmesh->batches[tno];
if (!sms->count)
continue;
if ((cl.worldmodel->textures[tno]->shader->flags & (SHADER_BLEND|SHADER_NODRAW)))
@ -1791,9 +1838,6 @@ static void Sh_GenShadowFace(dlight_t *l, shadowmesh_t *smesh, int face, float p
vec3_t t1,t2;
int smsize = SHADOWMAP_SIZE;
int tno;
mesh_t *m;
texture_t *tex;
// qglDepthRange(0, 1);
@ -1844,7 +1888,7 @@ static void Sh_GenShadowFace(dlight_t *l, shadowmesh_t *smesh, int face, float p
R_SetFrustum(proj, mvm);
if (smesh)
/* if (smesh)
for (tno = 0; tno < smesh->numsurftextures; tno++)
{
m = NULL;
@ -1853,7 +1897,7 @@ static void Sh_GenShadowFace(dlight_t *l, shadowmesh_t *smesh, int face, float p
tex = cl.worldmodel->textures[tno];
BE_DrawMesh_List(tex->shader, smesh->litsurfs[tno].count, smesh->litsurfs[tno].s, &tex->vbo, &tex->shader->defaulttextures, 0);
}
*/
BE_SelectMode(BEM_DEPTHONLY);
/*shadow meshes are always drawn as an external view*/
oxv = r_refdef.externalview;
@ -2138,14 +2182,14 @@ static void Sh_DrawEntLighting(dlight_t *light, vec3_t colour)
sm = &sh_tempshmesh;
if (sm)
{
for (tno = 0; tno < sm->numsurftextures; tno++)
for (tno = 0; tno < sm->numbatches; tno++)
{
if (!sm->litsurfs[tno].count)
if (!sm->batches[tno].count)
continue;
tex = cl.worldmodel->textures[tno];
tex = cl.worldmodel->shadowbatches[tno].tex;
if (tex->shader->flags & SHADER_NODLIGHT)
continue;
BE_DrawMesh_List(tex->shader, sm->litsurfs[tno].count, sm->litsurfs[tno].s, &tex->vbo, &tex->shader->defaulttextures, 0);
BE_DrawMesh_List(tex->shader, sm->batches[tno].count, sm->batches[tno].s, cl.worldmodel->shadowbatches[tno].vbo, &tex->shader->defaulttextures, 0);
}
switch(qrenderer)
@ -2787,6 +2831,20 @@ void Sh_DrawCrepuscularLight(dlight_t *dl, float *colours, batch_t **batches)
#endif
}
void Sh_PurgeShadowMeshes(void)
{
dlight_t *dl;
int i;
for (dl = cl_dlights, i=0; i<cl_maxdlights; i++, dl++)
{
if (dl->worldshadowmesh)
{
SH_FreeShadowMesh(dl->worldshadowmesh);
dl->worldshadowmesh = NULL;
}
}
}
void Sh_PreGenerateLights(void)
{
unsigned int ignoreflags;
@ -2823,6 +2881,16 @@ void Sh_PreGenerateLights(void)
}
}
void Com_ParseVector(char *str, vec3_t out)
{
str = COM_Parse(str);
out[0] = atof(com_token);
str = COM_Parse(str);
out[1] = atof(com_token);
str = COM_Parse(str);
out[2] = atof(com_token);
}
void Sh_DrawLights(qbyte *vis, batch_t **mbatches)
{
vec3_t colour;
@ -2831,6 +2899,7 @@ void Sh_DrawLights(qbyte *vis, batch_t **mbatches)
unsigned int ignoreflags;
extern cvar_t r_shadow_realtime_world, r_shadow_realtime_dlight;
extern cvar_t r_shadow_realtime_world_shadows, r_shadow_realtime_dlight_shadows;
extern cvar_t r_sun_dir, r_sun_colour;
if (!r_shadow_realtime_world.ival && !r_shadow_realtime_dlight.ival)
{
@ -2914,6 +2983,39 @@ void Sh_DrawLights(qbyte *vis, batch_t **mbatches)
}
}
if (1)
{
dlight_t sun = {0};
vec3_t sundir;
float dot;
Com_ParseVector(r_sun_dir.string, sundir);
Com_ParseVector(r_sun_colour.string, colour);
//fade it out if we're looking at an angle parallel to it (to avoid nasty visible graduations or backwards rays!)
dot = DotProduct(vpn, sundir);
dot = 1-dot;
dot *= dot;
dot = 1-dot;
VectorScale(colour, dot, colour);
if (colour[0] > 0.001 || colour[1] > 0.001 || colour[2] > 0.001)
{
//only do this if we can see some sky surfaces. pointless otherwise
batch_t *b;
for (b = cl.worldmodel->batches[SHADER_SORT_SKY]; b; b = b->next)
{
if (b->meshes)
break;
}
if (b)
{
VectorNormalize(sundir);
VectorMA(r_origin, 1000, sundir, sun.origin);
Sh_DrawCrepuscularLight(&sun, colour, mbatches);
}
}
}
switch(qrenderer)
{
#ifdef GLQUAKE

View file

@ -814,9 +814,9 @@ static const char *glsl_hdrs[] =
"wmat += m_bones[int(v_bone.y)] * v_weight.y;"
"wmat += m_bones[int(v_bone.z)] * v_weight.z;"
"wmat += m_bones[int(v_bone.w)] * v_weight.w;"
"n = vec4(v_normal.xyz, 1.0) * wmat;"
"t = vec4(v_svector.xyz, 1.0) * wmat;"
"b = vec4(v_tvector.xyz, 1.0) * wmat;"
"n = vec4(v_normal.xyz, 0.0) * wmat;"
"t = vec4(v_svector.xyz, 0.0) * wmat;"
"b = vec4(v_tvector.xyz, 0.0) * wmat;"
"return m_modelviewprojection * vec4(vec4(v_position.xyz, 1.0) * wmat, 1.0);"
"}\n"
"vec4 skeletaltransform_wnst(out vec3 w, out vec3 n, out vec3 t, out vec3 b)"
@ -826,9 +826,9 @@ static const char *glsl_hdrs[] =
"wmat += m_bones[int(v_bone.y)] * v_weight.y;"
"wmat += m_bones[int(v_bone.z)] * v_weight.z;"
"wmat += m_bones[int(v_bone.w)] * v_weight.w;"
"n = vec4(v_normal.xyz, 1.0) * wmat;"
"t = vec4(v_svector.xyz, 1.0) * wmat;"
"b = vec4(v_tvector.xyz, 1.0) * wmat;"
"n = vec4(v_normal.xyz, 0.0) * wmat;"
"t = vec4(v_svector.xyz, 0.0) * wmat;"
"b = vec4(v_tvector.xyz, 0.0) * wmat;"
"w = vec4(v_position.xyz, 1.0) * wmat;"
"return m_modelviewprojection * vec4(w, 1.0);"
"}\n"
@ -839,7 +839,7 @@ static const char *glsl_hdrs[] =
"wmat += m_bones[int(v_bone.y)] * v_weight.y;"
"wmat += m_bones[int(v_bone.z)] * v_weight.z;"
"wmat += m_bones[int(v_bone.w)] * v_weight.w;"
"n = vec4(v_normal.xyz, 1.0) * wmat;"
"n = vec4(v_normal.xyz, 0.0) * wmat;"
"return m_modelviewprojection * vec4(vec4(v_position.xyz, 1.0) * wmat, 1.0);"
"}\n"
"#else\n"
@ -1519,8 +1519,6 @@ rendererinfo_t openglrendererinfo = {
GLR_NewMap,
GLR_PreNewMap,
GLR_LightPoint,
Surf_AddStain,
Surf_LessenStains,

View file

@ -2090,7 +2090,7 @@ qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette)
Cvar_Hook(&_vid_wait_override, VID_Wait_Override_Callback);
Cvar_Hook(&vid_wndalpha, VID_WndAlpha_Override_Callback);
Cmd_AddRemCommand("vid_recenter", GLVID_Recenter_f);
Cmd_AddCommand("vid_recenter", GLVID_Recenter_f);
vid_initialized = true;
vid_initializing = false;

View file

@ -450,7 +450,7 @@ static void GL_SkyForceDepth(batch_t *batch)
if (!cls.allow_skyboxes && batch->texture) //allow a little extra fps.
{
BE_SelectMode(BEM_DEPTHONLY);
BE_DrawMesh_List(batch->shader, batch->meshes-batch->firstmesh, batch->mesh+batch->firstmesh, &batch->texture->vbo, &batch->shader->defaulttextures, batch->flags);
BE_DrawMesh_List(batch->shader, batch->meshes-batch->firstmesh, batch->mesh+batch->firstmesh, batch->vbo, &batch->shader->defaulttextures, batch->flags);
BE_SelectMode(BEM_STANDARD); /*skys only render in standard mode anyway, so this is safe*/
}
}

View file

@ -305,6 +305,7 @@ qboolean R_CullBox (vec3_t mins, vec3_t maxs);
qboolean R_CullEntityBox(entity_t *e, vec3_t modmins, vec3_t modmaxs);
qboolean R_CullSphere (vec3_t origin, float radius);
void Sh_PreGenerateLights(void);
void Sh_PurgeShadowMeshes(void);
#ifdef GLQUAKE
void R_TranslatePlayerSkin (int playernum);
@ -393,12 +394,10 @@ void R_DrawHLModel(entity_t *curent);
//
// gl_rlight.c
//
void R_RenderDlights (void);
void R_GenDlightBatches(batch_t *batches[]);
void R_InitFlashblends(void);
#ifdef GLQUAKE
void GLR_MarkQ2Lights (dlight_t *light, int bit, mnode_t *node);
int GLR_LightPoint (vec3_t p);
#endif
void GLQ3_LightGrid(model_t *mod, vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir);
void R_ReloadRTLights_f(void);

View file

@ -919,10 +919,7 @@ void LightFace (int surfnum)
wnorm[ch] = norm[c][ch];
}
total *= rangescale; // scale before clamping
#ifdef UTILITY
if (total > *out) //sorry - for qw
total = *out;
#else
#ifndef UTILITY
if (total > *rgbout) //sorry - for qw
total = *rgbout;
#endif

View file

@ -86,3 +86,874 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#endif\n"
},
#endif
#ifdef GLQUAKE
{QR_OPENGL, 110, "colourtint",
//this glsl shader is useful for cubemapped post processing effects (see csaddon for an example)
"varying vec4 tf;\n"
"#ifdef VERTEX_SHADER\n"
"void main ()\n"
"{\n"
"gl_Position = tf = vec4(v_position.xy,-1.0, 1.0);\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform sampler2D s_t0;\n"
"uniform sampler3D s_t1;\n"
"void main()\n"
"{\n"
"vec2 fc;\n"
"fc = tf.xy / tf.w;\n"
"vec3 raw = texture2D(s_t0, (1.0 + fc) / 2.0).rgb;\n"
"#define LUTSIZE 16.0\n"
"vec3 scale = vec3((LUTSIZE-1.0)/LUTSIZE);\n"
"vec3 bias = vec3(1.0/(2.0*LUTSIZE));\n"
"gl_FragColor = texture3D(s_t1, raw * scale + bias);\n"
"}\n"
"#endif\n"
},
#endif
#ifdef GLQUAKE
{QR_OPENGL, 110, "crepuscular_opaque",
//opaque surfaces are drawn to the render target to mask out skies
"#ifdef VERTEX_SHADER\n"
"void main ()\n"
"{\n"
"gl_Position = ftetransform();\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"void main()\n"
"{\n"
"gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);\n"
"}\n"
"#endif\n"
},
#endif
#ifdef GLQUAKE
{QR_OPENGL, 110, "crepuscular_rays",
"!!cvarf crep_decay\n"
"!!cvarf crep_density\n"
"!!cvarf crep_weight\n"
//this is a post-processing shader, drawn in 2d
//there will be a render target containing sky surfaces drawn with crepuscular_sky, and everything else drawn with crepuscular_opaque (to mask out the sky)
//this shader then just smudges the sky out a bit as though its coming from the sun or whatever through the clouds.
//yoinked from http://fabiensanglard.net/lightScattering/index.php
"varying vec2 tc;\n"
"#ifdef VERTEX_SHADER\n"
"attribute vec2 v_texcoord;\n"
"void main ()\n"
"{\n"
"tc = v_texcoord;\n"
"gl_Position = v_position;\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"const float crep_decay = 0.94;\n"
"const float crep_density = 0.5;\n"
"const float crep_weight = 0.2;\n"
"uniform vec3 l_lightcolour;\n"
"uniform vec3 l_lightscreen;\n"
"uniform sampler2D s_t0;\n"
"const int NUM_SAMPLES = 100;\n"
"void main()\n"
"{\n"
"vec2 deltaTextCoord = vec2(tc.st - l_lightscreen.xy);\n"
"vec2 textCoo = tc.st;\n"
"deltaTextCoord *= 1.0 / float(NUM_SAMPLES) * crep_density;\n"
"float illuminationDecay = 1.0;\n"
"for(int i=0; i < NUM_SAMPLES ; i++)\n"
"{\n"
"textCoo -= deltaTextCoord;\n"
"vec4 sample = texture2D(s_t0, textCoo);\n"
"sample *= illuminationDecay * crep_weight;\n"
"gl_FragColor += sample;\n"
"illuminationDecay *= crep_decay;\n"
"}\n"
"gl_FragColor *= vec4(l_lightcolour, 1.0);\n"
"}\n"
"#endif\n"
},
#endif
#ifdef GLQUAKE
{QR_OPENGL, 110, "crepuscular_sky",
//pretty much a regular sky shader
//though in reality we should render a sun circle in the middle.
//still, its kinda cool to have scrolling clouds masking out parts of the sun.
"#ifdef VERTEX_SHADER\n"
"varying vec3 pos;\n"
"void main ()\n"
"{\n"
"pos = v_position.xyz;\n"
"gl_Position = ftetransform();\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform float e_time;\n"
"uniform vec3 e_eyepos;\n"
"varying vec3 pos;\n"
"uniform sampler2D s_t0;\n"
"uniform sampler2D s_t1;\n"
"void main ()\n"
"{\n"
"vec2 tccoord;\n"
"vec3 dir = pos - e_eyepos;\n"
"dir.z *= 3.0;\n"
"dir.xy /= 0.5*length(dir);\n"
"tccoord = (dir.xy + e_time*0.03125);\n"
"vec3 solid = vec3(texture2D(s_t0, tccoord));\n"
"tccoord = (dir.xy + e_time*0.0625);\n"
"vec4 clouds = texture2D(s_t1, tccoord);\n"
"gl_FragColor.rgb = (solid.rgb*(1.0-clouds.a)) + (clouds.a*clouds.rgb);\n"
"}\n"
"#endif\n"
},
#endif
#ifdef GLQUAKE
{QR_OPENGL, 110, "default2d",
//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"
"attribute vec4 v_colour;\n"
"varying vec2 tc;\n"
"varying vec4 vc;\n"
"void main ()\n"
"{\n"
"tc = v_texcoord;\n"
"vc = v_colour;\n"
"gl_Position = ftetransform();\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform sampler2D s_t0;\n"
"in vec2 tc;\n"
"varying vec4 vc;\n"
"void main ()\n"
"{\n"
"gl_FragColor = texture2D(s_t0, tc) * vc;\n"
"}\n"
"#endif\n"
},
#endif
#ifdef GLQUAKE
{QR_OPENGL, 110, "defaultadditivesprite",
"!!permu FOG\n"
//meant to be used for additive stuff. presumably particles and sprites. though actually its only flashblend effects that use this at the time of writing.
//includes fog, apparently.
"#include \"sys/fog.h\"\n"
"#ifdef VERTEX_SHADER\n"
"attribute vec2 v_texcoord;\n"
"attribute vec4 v_colour;\n"
"varying vec2 tc;\n"
"varying vec4 vc;\n"
"void main ()\n"
"{\n"
"tc = v_texcoord;\n"
"vc = v_colour;\n"
"gl_Position = ftetransform();\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform sampler2D s_t0;\n"
"varying vec2 tc;\n"
"varying vec4 vc;\n"
"uniform vec4 e_colourident;\n"
"void main ()\n"
"{\n"
"gl_FragColor = fog4additive(texture2D(s_t0, tc) * vc * e_colourident);\n"
"}\n"
"#endif\n"
},
#endif
#ifdef GLQUAKE
{QR_OPENGL, 110, "defaultskin",
"!!permu FULLBRIGHT\n"
"!!permu UPPERLOWER\n"
"!!permu FRAMEBLEND\n"
"!!permu SKELETAL\n"
"!!permu FOG\n"
//standard shader used for models.
//must support skeletal and 2-way vertex blending or Bad Things Will Happen.
//the vertex shader is responsible for calculating lighting values.
"varying vec2 tc;\n"
"varying vec3 light;\n"
"#ifdef VERTEX_SHADER\n"
"#include \"sys/skeletal.h\"\n"
"attribute vec2 v_texcoord;\n"
"uniform vec3 e_light_dir;\n"
"uniform vec3 e_light_mul;\n"
"uniform vec3 e_light_ambient;\n"
"void main ()\n"
"{\n"
"vec3 n;\n"
"gl_Position = skeletaltransform_n(n);\n"
"light = e_light_ambient + (dot(n,e_light_dir)*e_light_mul);\n"
"tc = v_texcoord;\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"#include \"sys/fog.h\"\n"
"uniform sampler2D s_t0;\n"
"#ifdef LOWER\n"
"uniform sampler2D s_t1;\n"
"uniform vec3 e_lowercolour;\n"
"#endif\n"
"#ifdef UPPER\n"
"uniform sampler2D s_t2;\n"
"uniform vec3 e_uppercolour;\n"
"#endif\n"
"#ifdef FULLBRIGHT\n"
"uniform sampler2D s_t3;\n"
"#endif\n"
"uniform vec4 e_colourident;\n"
"void main ()\n"
"{\n"
"vec4 col, sp;\n"
"col = texture2D(s_t0, tc);\n"
"#ifdef UPPER\n"
"vec4 uc = texture2D(s_t2, tc);\n"
"col.rgb = mix(col.rgb, uc.rgb*e_uppercolour, uc.a);\n"
"#endif\n"
"#ifdef LOWER\n"
"vec4 lc = texture2D(s_t1, tc);\n"
"col.rgb = mix(col.rgb, lc.rgb*e_lowercolour, lc.a);\n"
"#endif\n"
"col.rgb *= light;\n"
"#ifdef FULLBRIGHT\n"
"vec4 fb = texture2D(s_t3, tc);\n"
"col.rgb = mix(col.rgb, fb.rgb, fb.a);\n"
"#endif\n"
"gl_FragColor = fog4(col * e_colourident);\n"
"}\n"
"#endif\n"
},
#endif
#ifdef GLQUAKE
{QR_OPENGL, 110, "defaultsky",
//regular sky shader for scrolling q1 skies
//the sky surfaces are thrown through this as-is.
"#ifdef VERTEX_SHADER\n"
"varying vec3 pos;\n"
"void main ()\n"
"{\n"
"pos = v_position.xyz;\n"
"gl_Position = ftetransform();\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform float e_time;\n"
"uniform vec3 e_eyepos;\n"
"varying vec3 pos;\n"
"uniform sampler2D s_t0;\n"
"uniform sampler2D s_t1;\n"
"void main ()\n"
"{\n"
"vec2 tccoord;\n"
"vec3 dir = pos - e_eyepos;\n"
"dir.z *= 3.0;\n"
"dir.xy /= 0.5*length(dir);\n"
"tccoord = (dir.xy + e_time*0.03125);\n"
"vec3 solid = vec3(texture2D(s_t0, tccoord));\n"
"tccoord = (dir.xy + e_time*0.0625);\n"
"vec4 clouds = texture2D(s_t1, tccoord);\n"
"gl_FragColor.rgb = (solid.rgb*(1.0-clouds.a)) + (clouds.a*clouds.rgb);\n"
"}\n"
"#endif\n"
},
#endif
#ifdef GLQUAKE
{QR_OPENGL, 110, "defaultsprite",
"!!permu FOG\n"
//used by both particles and sprites.
//note the fog blending mode is all that differs from defaultadditivesprite
"#include \"sys/fog.h\"\n"
"#ifdef VERTEX_SHADER\n"
"attribute vec2 v_texcoord;\n"
"attribute vec4 v_colour;\n"
"varying vec2 tc;\n"
"varying vec4 vc;\n"
"void main ()\n"
"{\n"
"tc = v_texcoord;\n"
"vc = v_colour;\n"
"gl_Position = ftetransform();\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform sampler2D s_t0;\n"
"varying vec2 tc;\n"
"varying vec4 vc;\n"
"uniform vec4 e_colourident;\n"
"void main ()\n"
"{\n"
"gl_FragColor = fog4blend(texture2D(s_t0, tc) * vc * e_colourident);\n"
"}\n"
"#endif\n"
},
#endif
#ifdef GLQUAKE
{QR_OPENGL, 110, "defaultwall",
"!!permu OFFSETMAPPING\n"
"!!permu FULLBRIGHT\n"
"!!permu FOG\n"
"!!cvarf r_glsl_offsetmapping_scale\n"
//this is what normally draws all of your walls, even with rtlights disabled
//note that the '286' preset uses drawflat_walls instead.
"#include \"sys/fog.h\"\n"
"#if defined(OFFSETMAPPING)\n"
"varying vec3 eyevector;\n"
"#endif\n"
"#ifdef VERTEX_SHADER\n"
"attribute vec2 v_texcoord;\n"
"attribute vec2 v_lmcoord;\n"
"varying vec2 tc, lm;\n"
"#if defined(OFFSETMAPPING)\n"
"uniform vec3 e_eyepos;\n"
"attribute vec3 v_normal;\n"
"attribute vec3 v_svector;\n"
"attribute vec3 v_tvector;\n"
"#endif\n"
"void main ()\n"
"{\n"
"#if defined(OFFSETMAPPING)\n"
"vec3 eyeminusvertex = e_eyepos - v_position.xyz;\n"
"eyevector.x = dot(eyeminusvertex, v_svector.xyz);\n"
"eyevector.y = -dot(eyeminusvertex, v_tvector.xyz);\n"
"eyevector.z = dot(eyeminusvertex, v_normal.xyz);\n"
"#endif\n"
"tc = v_texcoord;\n"
"lm = v_lmcoord;\n"
"gl_Position = ftetransform();\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform sampler2D s_t0;\n"
"uniform sampler2D s_t1;\n"
"#ifdef OFFSETMAPPING\n"
"uniform sampler2D s_t2;\n"
"#endif\n"
"#ifdef FULLBRIGHT\n"
"uniform sampler2D s_t4;\n"
"#endif\n"
"varying vec2 tc, lm;\n"
"uniform vec4 e_lmscale;\n"
"uniform vec4 e_colourident;\n"
"#ifdef OFFSETMAPPING\n"
"#include \"sys/offsetmapping.h\"\n"
"#endif\n"
"void main ()\n"
"{\n"
"#ifdef OFFSETMAPPING\n"
"vec2 tcoffsetmap = offsetmap(s_t2, tc, eyevector);\n"
"#define tc tcoffsetmap\n"
"#endif\n"
"gl_FragColor = texture2D(s_t0, tc) * texture2D(s_t1, lm) * e_lmscale;\n"
"#ifdef FULLBRIGHT\n"
"gl_FragColor.rgb += texture2D(s_t4, tc).rgb;\n"
"#endif\n"
"gl_FragColor = gl_FragColor * e_colourident;\n"
"#ifdef FOG\n"
"gl_FragColor = fog4(gl_FragColor);\n"
"#endif\n"
"}\n"
"#endif\n"
},
#endif
#ifdef GLQUAKE
{QR_OPENGL, 110, "defaultwarp",
"!!cvarf r_wateralpha\n"
"!!permu FOG\n"
//this is the shader that's responsible for drawing default q1 turbulant water surfaces
//this is expected to be moderately fast.
"#include \"sys/fog.h\"\n"
"varying vec2 tc;\n"
"#ifdef VERTEX_SHADER\n"
"attribute vec2 v_texcoord;\n"
"void main ()\n"
"{\n"
"tc = v_texcoord.st;\n"
"gl_Position = ftetransform();\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform sampler2D s_t0;\n"
"uniform float e_time;\n"
"uniform float cvar_r_wateralpha;\n"
"void main ()\n"
"{\n"
"vec2 ntc;\n"
"ntc.s = tc.s + sin(tc.t+e_time)*0.125;\n"
"ntc.t = tc.t + sin(tc.s+e_time)*0.125;\n"
"vec3 ts = vec3(texture2D(s_t0, ntc));\n"
"gl_FragColor = fog4(vec4(ts, cvar_r_wateralpha));\n"
"}\n"
"#endif\n"
},
#endif
#ifdef GLQUAKE
{QR_OPENGL, 110, "drawflat_wall",
"!!cvarv r_floorcolor\n"
"!!cvarv r_wallcolor\n"
"!!permu FOG\n"
//this is for the '286' preset walls, and just draws lightmaps coloured based upon surface normals.
"#include \"sys/fog.h\"\n"
"varying vec4 col;\n"
"#ifdef VERTEX_SHADER\n"
"attribute vec3 v_normal;\n"
"attribute vec2 v_lmcoord;\n"
"varying vec2 lm;\n"
"uniform vec3 cvar_r_wallcolor;\n"
"uniform vec3 cvar_r_floorcolor;\n"
"uniform vec4 e_lmscale;\n"
"void main ()\n"
"{\n"
"col = vec4(e_lmscale.rgb/255.0 * ((v_normal.z < 0.73)?cvar_r_wallcolor:cvar_r_floorcolor), e_lmscale.a);\n"
"lm = v_lmcoord;\n"
"gl_Position = ftetransform();\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform sampler2D s_t0;\n"
"varying vec2 lm;\n"
"void main ()\n"
"{\n"
"gl_FragColor = fog4(col * texture2D(s_t0, lm));\n"
"}\n"
"#endif\n"
},
#endif
#ifdef GLQUAKE
{QR_OPENGL, 110, "lpp_depthnorm",
"!!permu BUMP\n"
"!!permu SKELETAL\n"
//light pre-pass rendering (defered lighting)
//this is the initial pass, that draws the surface normals and depth to the initial colour buffer
"varying vec3 norm, tang, bitang;\n"
"#if defined(BUMP)\n"
"varying vec2 tc;\n"
"#endif\n"
"#ifdef VERTEX_SHADER\n"
"#include \"sys/skeletal.h\"\n"
"attribute vec2 v_texcoord;\n"
"void main()\n"
"{\n"
"#if defined(BUMP)\n"
"gl_Position = skeletaltransform_nst(norm, tang, bitang);\n"
"tc = v_texcoord;\n"
"#else\n"
"gl_Position = skeletaltransform_n(norm);\n"
"#endif\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"#if defined(BUMP)\n"
"uniform sampler2D s_t0;\n"
"#endif\n"
"void main()\n"
"{\n"
"vec3 onorm;\n"
"#if defined(BUMP)\n"
"vec3 bm = 2.0*texture2D(s_t0, tc).xyz - 1.0;\n"
"onorm = normalize(bm.x * tang + bm.y * bitang + bm.z * norm);\n"
"#else\n"
"onorm = norm;\n"
"#endif\n"
"gl_FragColor = vec4(onorm.xyz, gl_FragCoord.z / gl_FragCoord.w);\n"
"}\n"
"#endif\n"
},
#endif
#ifdef GLQUAKE
{QR_OPENGL, 110, "lpp_light",
//this shader is a light shader. ideally drawn with a quad covering the entire region
//the output is contribution from this light (which will be additively blended)
//you can blame Electro for much of the maths in here.
//fixme: no fog
"varying vec4 tf;\n"
"#ifdef VERTEX_SHADER\n"
"void main()\n"
"{\n"
"tf = ftetransform();\n"
"gl_Position = tf;\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform sampler2D s_t0;\n"
"uniform vec3 l_lightposition;\n"
"uniform mat4 m_invviewprojection;\n"
"uniform vec3 l_lightcolour;\n"
"uniform float l_lightradius;\n"
"vec3 calcLightWorldPos(vec2 screenPos, float depth)\n"
"{\n"
"vec4 pos;\n"
"pos.x = screenPos.x;\n"
"pos.y = screenPos.y;\n"
"pos.z = depth;\n"
"pos.w = 1.0;\n"
"pos = m_invviewprojection * pos;\n"
"return pos.xyz / pos.w;\n"
"}\n"
"void main ()\n"
"{\n"
"vec3 lightColour = l_lightcolour.rgb;\n"
"float lightIntensity = 1.0;\n"
"float lightAttenuation = l_lightradius; // fixme: just use the light radius for now, use better near/far att math separately once working\n"
"float radiusFar = l_lightradius;\n"
"float radiusNear = l_lightradius*0.5;\n"
"vec2 fc;\n"
"fc = tf.xy / tf.w;\n"
"vec4 data = texture2D(s_t0, (1.0 + fc) / 2.0);\n"
"float depth = data.a;\n"
"vec3 norm = data.xyz;\n"
/* calc where the wall that generated this sample came from */
"vec3 worldPos = calcLightWorldPos(fc, depth);\n"
/*calc diffuse lighting term*/
"vec3 lightDir = l_lightposition - worldPos;\n"
"float zdiff = 1.0 - clamp(length(lightDir) / lightAttenuation, 0.0, 1.0);\n"
"float atten = (radiusFar * zdiff) / (radiusFar - radiusNear);\n"
"atten = pow(atten, 2.0);\n"
"lightDir = normalize(lightDir);\n"
"float nDotL = dot(norm, lightDir) * atten;\n"
"float lightDiffuse = max(0.0, nDotL);\n"
"gl_FragColor = vec4(lightDiffuse * (lightColour * lightIntensity), 1.0);\n"
"}\n"
"#endif\n"
},
#endif
#ifdef GLQUAKE
{QR_OPENGL, 110, "lpp_wall",
//the final defered lighting pass.
//the lighting values were written to some render target, which is fed into this shader, and now we draw all the wall textures with it.
"varying vec2 tc, lm;\n"
"varying vec4 tf;\n"
"#ifdef VERTEX_SHADER\n"
"attribute vec2 v_texcoord;\n"
"attribute vec2 v_lmcoord;\n"
"void main ()\n"
"{\n"
"tc = v_texcoord;\n"
"lm = v_lmcoord;\n"
"gl_Position = tf = ftetransform();\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform sampler2D s_t0;\n"
"uniform sampler2D s_t1;\n"
"uniform sampler2D s_t2;\n"
"uniform vec4 e_lmscale;\n"
"void main ()\n"
"{\n"
"vec2 nst;\n"
"nst = tf.xy / tf.w;\n"
"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*lmscale;\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"
"gl_FragColor = vec4((diff + lmsamp) * c.xyz, 1.0);\n"
"}\n"
"#endif\n"
},
#endif
#ifdef GLQUAKE
{QR_OPENGL, 110, "postproc_fisheye",
"!!cvarf ffov\n"
//fisheye view rendering, for silly fovs that are still playable.
"#ifdef VERTEX_SHADER\n"
"attribute vec2 v_texcoord;\n"
"varying vec2 texcoord;\n"
"void main()\n"
"{\n"
"texcoord = v_texcoord.xy;\n"
"gl_Position = ftetransform();\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform samplerCube s_t0;\n"
"varying vec2 texcoord;\n"
"uniform float cvar_ffov;\n"
"void main()\n"
"{\n"
"vec3 tc; \n"
"vec2 d; \n"
"vec2 ang; \n"
"d = texcoord; \n"
"ang.x = sqrt(d.x*d.x+d.y*d.y)*radians(cvar_ffov); \n"
"ang.y = -atan(d.y, d.x); \n"
"tc.x = sin(ang.x) * cos(ang.y); \n"
"tc.y = sin(ang.x) * sin(ang.y); \n"
"tc.z = cos(ang.x); \n"
"gl_FragColor = textureCube(s_t0, tc);\n"
"}\n"
"#endif\n"
},
#endif
#ifdef GLQUAKE
{QR_OPENGL, 110, "postproc_panorama",
"!!cvarf ffov\n"
//panoramic view rendering, for promo map shots or whatever.
"#ifdef VERTEX_SHADER\n"
"attribute vec2 v_texcoord;\n"
"varying vec2 texcoord;\n"
"void main()\n"
"{\n"
"texcoord = v_texcoord.xy;\n"
"gl_Position = ftetransform();\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform samplerCube s_t0;\n"
"varying vec2 texcoord;\n"
"uniform float cvar_ffov;\n"
"void main()\n"
"{\n"
"vec3 tc; \n"
"float ang; \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, "rtlight",
"!!permu BUMP\n"
"!!permu SPECULAR\n"
"!!permu OFFSETMAPPING\n"
"!!permu SKELETAL\n"
"!!permu FOG\n"
"!!cvarf r_glsl_offsetmapping_scale\n"
//this is the main shader responsible for realtime dlights.
//texture units:
//s0=diffuse, s1=normal, s2=specular, s3=shadowmap
//custom modifiers:
//PCF(shadowmap)
//CUBE(projected cubemap)
"varying vec2 tcbase;\n"
"varying vec3 lightvector;\n"
"#if defined(SPECULAR) || defined(OFFSETMAPPING)\n"
"varying vec3 eyevector;\n"
"#endif\n"
"#if defined(PCF) || defined(CUBE)\n"
"varying vec4 vshadowcoord;\n"
"uniform mat4 l_projmatrix;\n"
"#endif\n"
"#ifdef VERTEX_SHADER\n"
"#include \"sys/skeletal.h\"\n"
"uniform vec3 l_lightposition;\n"
"attribute vec2 v_texcoord;\n"
"#if defined(SPECULAR) || defined(OFFSETMAPPING)\n"
"uniform vec3 e_eyepos;\n"
"#endif\n"
"void main ()\n"
"{\n"
"vec3 n, s, t, w;\n"
"gl_Position = skeletaltransform_wnst(w,n,s,t);\n"
"tcbase = v_texcoord; //pass the texture coords straight through\n"
"vec3 lightminusvertex = l_lightposition - w.xyz;\n"
"lightvector.x = dot(lightminusvertex, s.xyz);\n"
"lightvector.y = dot(lightminusvertex, t.xyz);\n"
"lightvector.z = dot(lightminusvertex, n.xyz);\n"
"#if defined(SPECULAR)||defined(OFFSETMAPPING)\n"
"vec3 eyeminusvertex = e_eyepos - w.xyz;\n"
"eyevector.x = dot(eyeminusvertex, s.xyz);\n"
"eyevector.y = -dot(eyeminusvertex, t.xyz);\n"
"eyevector.z = dot(eyeminusvertex, n.xyz);\n"
"#endif\n"
"#if defined(PCF) || defined(SPOT) || defined(PROJECTION) || defined(CUBE)\n"
"vshadowcoord = l_projmatrix*vec4(w.xyz, 1.0);\n"
"#endif\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"#include \"sys/fog.h\"\n"
"uniform sampler2D s_t0;\n"
"#if defined(BUMP) || defined(SPECULAR) || defined(OFFSETMAPPING)\n"
"uniform sampler2D s_t1;\n"
"#endif\n"
"#ifdef SPECULAR\n"
"uniform sampler2D s_t2;\n"
"#endif\n"
"#ifdef CUBE\n"
"uniform samplerCube s_t3;\n"
"#endif\n"
"#ifdef PCF\n"
"#ifdef CUBE\n"
"uniform samplerCubeShadow s_t7;\n"
"#else\n"
"uniform sampler2DShadow s_t7;\n"
"#endif\n"
"#endif\n"
"uniform float l_lightradius;\n"
"uniform vec3 l_lightcolour;\n"
"uniform vec3 l_lightcolourscale;\n"
"#ifdef OFFSETMAPPING\n"
"#include \"sys/offsetmapping.h\"\n"
"#endif\n"
"void main ()\n"
"{\n"
"#ifdef OFFSETMAPPING\n"
"vec2 tcoffsetmap = offsetmap(s_t1, tcbase, eyevector);\n"
"#define tcbase tcoffsetmap\n"
"#endif\n"
"vec3 bases = vec3(texture2D(s_t0, tcbase));\n"
"#if defined(BUMP) || defined(SPECULAR)\n"
"vec3 bumps = vec3(texture2D(s_t1, tcbase)) - 0.5;\n"
"#endif\n"
"#ifdef SPECULAR\n"
"vec4 specs = texture2D(s_t2, tcbase);\n"
"#endif\n"
"vec3 nl = normalize(lightvector);\n"
"float colorscale = max(1.0 - dot(lightvector, lightvector)/(l_lightradius*l_lightradius), 0.0);\n"
"vec3 diff;\n"
"#ifdef BUMP\n"
"diff = bases * (l_lightcolourscale.x + l_lightcolourscale.y * max(dot(2.0*bumps, nl), 0.0));\n"
"#else\n"
"diff = bases * (l_lightcolourscale.x + l_lightcolourscale.y * max(dot(vec3(0.0, 0.0, 1.0), nl), 0.0));\n"
"#endif\n"
"#ifdef SPECULAR\n"
"vec3 halfdir = normalize(lightvector - normalize(eyevector));\n"
"float spec = pow(max(dot(halfdir, bumps), 0.0), 1.0 + 32.0 * specs.a);\n"
"diff += spec * specs.rgb * l_lightcolourscale.z;\n"
"#endif\n"
"#ifdef CUBE\n"
"diff *= textureCube(s_t3, vshadowcoord.xyz).rgb;\n"
"#endif\n"
"#ifdef PCF\n"
"#if defined(SPOT)\n"
"const float texx = 512.0;\n"
"const float texy = 512.0;\n"
"vec4 shadowcoord = vshadowcoord;\n"
"#else\n"
"const float texx = 512.0;\n"
"const float texy = 512.0;\n"
"vec4 shadowcoord;\n"
"shadowcoord.zw = vshadowcoord.zw;\n"
"shadowcoord.xy = vshadowcoord.xy;\n"
"#endif\n"
"#ifdef CUBE\n"
"const float xPixelOffset = 1.0/texx; const float yPixelOffset = 1.0/texy; float s = 0.0;\n"
"s += shadowCubeProj(s_t7, shadowcoord + vec4(-1.0 * xPixelOffset * shadowcoord.w, -1.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n"
"s += shadowCubeProj(s_t7, shadowcoord + vec4(-1.0 * xPixelOffset * shadowcoord.w, 0.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n"
"s += shadowCubeProj(s_t7, shadowcoord + vec4(-1.0 * xPixelOffset * shadowcoord.w, 1.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n"
"s += shadowCubeProj(s_t7, shadowcoord + vec4(0.0 * xPixelOffset * shadowcoord.w, -1.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n"
"s += shadowCubeProj(s_t7, shadowcoord + vec4(0.0 * xPixelOffset * shadowcoord.w, 0.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n"
"s += shadowCubeProj(s_t7, shadowcoord + vec4(0.0 * xPixelOffset * shadowcoord.w, 1.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n"
"s += shadowCubeProj(s_t7, shadowcoord + vec4(1.0 * xPixelOffset * shadowcoord.w, -1.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n"
"s += shadowCubeProj(s_t7, shadowcoord + vec4(1.0 * xPixelOffset * shadowcoord.w, 0.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n"
"s += shadowCubeProj(s_t7, shadowcoord + vec4(1.0 * xPixelOffset * shadowcoord.w, 1.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n"
"colorscale *= s/9.0;\n"
"#else\n"
"const float xPixelOffset = 1.0/texx; const float yPixelOffset = 1.0/texy; float s = 0.0;\n"
"s += shadow2DProj(s_t7, shadowcoord + vec4(-1.0 * xPixelOffset * shadowcoord.w, -1.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n"
"s += shadow2DProj(s_t7, shadowcoord + vec4(-1.0 * xPixelOffset * shadowcoord.w, 0.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n"
"s += shadow2DProj(s_t7, shadowcoord + vec4(-1.0 * xPixelOffset * shadowcoord.w, 1.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n"
"s += shadow2DProj(s_t7, shadowcoord + vec4(0.0 * xPixelOffset * shadowcoord.w, -1.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n"
"s += shadow2DProj(s_t7, shadowcoord + vec4(0.0 * xPixelOffset * shadowcoord.w, 0.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n"
"s += shadow2DProj(s_t7, shadowcoord + vec4(0.0 * xPixelOffset * shadowcoord.w, 1.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n"
"s += shadow2DProj(s_t7, shadowcoord + vec4(1.0 * xPixelOffset * shadowcoord.w, -1.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n"
"s += shadow2DProj(s_t7, shadowcoord + vec4(1.0 * xPixelOffset * shadowcoord.w, 0.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n"
"s += shadow2DProj(s_t7, shadowcoord + vec4(1.0 * xPixelOffset * shadowcoord.w, 1.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n"
"colorscale *= s/9.0;\n"
"#endif\n"
"#endif\n"
"#if defined(SPOT)\n"
"if (shadowcoord.w < 0.0) discard;\n"
"vec2 spot = ((shadowcoord.st)/shadowcoord.w - 0.5)*2.0;colorscale*=1.0-(dot(spot,spot));\n"
"#endif\n"
"#if defined(PROJECTION)\n"
"l_lightcolour *= texture2d(s_t3, shadowcoord);\n"
"#endif\n"
"gl_FragColor.rgb = fog3additive(diff*colorscale*l_lightcolour);\n"
"}\n"
"#endif\n"
},
#endif
#ifdef GLQUAKE
{QR_OPENGL, 110, "underwaterwarp",
"!!cvarf r_waterwarp\n"
//this is a post processing shader that is drawn fullscreen whenever the view is underwater.
//its generally expected to warp the view a little.
"#ifdef VERTEX_SHADER\n"
"attribute vec2 v_texcoord;\n"
"varying vec2 v_stc;\n"
"varying vec2 v_warp;\n"
"varying vec2 v_edge;\n"
"uniform float e_time;\n"
"void main ()\n"
"{\n"
"gl_Position = ftetransform();\n"
"v_stc = (1.0+(gl_Position.xy / gl_Position.w))/2.0;\n"
"v_warp.s = e_time * 0.25 + v_texcoord.s;\n"
"v_warp.t = e_time * 0.25 + v_texcoord.t;\n"
"v_edge = v_texcoord.xy;\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"varying vec2 v_stc;\n"
"varying vec2 v_warp;\n"
"varying vec2 v_edge;\n"
"uniform sampler2D s_t0;/*$currentrender*/\n"
"uniform sampler2D s_t1;/*warp image*/\n"
"uniform sampler2D s_t2;/*edge image*/\n"
"uniform vec3 e_rendertexturescale;\n"
"uniform float cvar_r_waterwarp;\n"
"void main ()\n"
"{\n"
"float amptemp;\n"
"vec3 edge;\n"
"edge = texture2D( s_t2, v_edge ).rgb;\n"
"amptemp = (0.010 / 0.625) * cvar_r_waterwarp * edge.x;\n"
"vec3 offset;\n"
"offset = texture2D( s_t1, v_warp ).rgb;\n"
"offset.x = (offset.x - 0.5) * 2.0;\n"
"offset.y = (offset.y - 0.5) * 2.0;\n"
"vec2 temp;\n"
"temp.x = v_stc.x + offset.x * amptemp;\n"
"temp.y = v_stc.y + offset.y * amptemp;\n"
"gl_FragColor = texture2D( s_t0, temp*e_rendertexturescale.st );\n"
"}\n"
"#endif\n"
},
#endif

View file

@ -226,6 +226,9 @@ typedef struct shaderpass_s {
T_GEN_SOURCECOLOUR, //used for render-to-texture targets
T_GEN_SOURCEDEPTH, //used for render-to-texture targets
T_GEN_REFLECTION, //reflection image (mirror-as-fbo)
T_GEN_REFRACTION, //refraction image (portal-as-fbo)
T_GEN_SOURCECUBE, //used for render-to-texture targets
T_GEN_VIDEOMAP, //use the media playback as an image source, updating each frame for which it is visible
@ -414,7 +417,9 @@ struct shader_s
SHADER_NODLIGHT = 1 << 15, //from surfaceflags
SHADER_HASLIGHTMAP = 1 << 16,
SHADER_HASTOPBOTTOM = 1 << 17,
SHADER_STATICDATA = 1 << 18 //set if true: no deforms, no tcgen, rgbgen=identitylighting, alphagen=identity, tmu0=st + tmu1=lm(if available) for every pass, no norms
SHADER_STATICDATA = 1 << 18, //set if true: no deforms, no tcgen, rgbgen=identitylighting, alphagen=identity, tmu0=st + tmu1=lm(if available) for every pass, no norms
SHADER_HASREFLECT = 1 << 19,
SHADER_HASREFRACT = 1 << 20
} flags;
program_t *prog;

View file

@ -69,6 +69,22 @@ void *Hash_GetInsensative(hashtable_t *table, const char *name)
}
return NULL;
}
void *Hash_GetInsensativeBucket(hashtable_t *table, const char *name)
{
unsigned int bucknum = Hash_KeyInsensative(name, table->numbuckets);
bucket_t *buck;
buck = table->bucket[bucknum];
while(buck)
{
if (!stricmp(name, buck->key.string))
return buck;
buck = buck->next;
}
return NULL;
}
void *Hash_GetKey(hashtable_t *table, unsigned int key)
{
unsigned int bucknum = key%table->numbuckets;
@ -237,32 +253,35 @@ void Hash_Remove(hashtable_t *table, const char *name)
void Hash_RemoveData(hashtable_t *table, const char *name, void *data)
{
unsigned int bucknum = Hash_Key(name, table->numbuckets);
bucket_t *buck;
bucket_t **link, *buck;
buck = table->bucket[bucknum];
if (buck->data == data)
if (!STRCMP(name, buck->key.string))
for (link = &table->bucket[bucknum]; *link; link = &(*link)->next)
{
buck = *link;
if (buck->data == data && !stricmp(name, buck->key.string))
{
table->bucket[bucknum] = buck->next;
*link = buck->next;
return;
}
while(buck->next)
{
if (buck->next->data == data)
if (!STRCMP(name, buck->next->key.string))
{
buck->next = buck->next->next;
return;
}
buck = buck->next;
}
return;
}
void Hash_RemoveBucket(hashtable_t *table, const char *name, bucket_t *data)
{
unsigned int bucknum = Hash_Key(name, table->numbuckets);
bucket_t **link, *buck;
for (link = &table->bucket[bucknum]; *link; link = &(*link)->next)
{
buck = *link;
if (buck == data && !stricmp(name, buck->key.string))
{
*link = buck->next;
return;
}
}
return;
}
void Hash_RemoveKey(hashtable_t *table, unsigned int key)
{

View file

@ -25,6 +25,7 @@ void Hash_InitTable(hashtable_t *table, unsigned int numbucks, void *mem); //mem
unsigned int Hash_Key(const char *name, unsigned int modulus);
void *Hash_Get(hashtable_t *table, const char *name);
void *Hash_GetInsensative(hashtable_t *table, const char *name);
void *Hash_GetInsensativeBucket(hashtable_t *table, const char *name);
void *Hash_GetKey(hashtable_t *table, unsigned int key);
void *Hash_GetNext(hashtable_t *table, const char *name, void *old);
void *Hash_GetNextInsensative(hashtable_t *table, const char *name, void *old);
@ -33,6 +34,7 @@ void *Hash_Add(hashtable_t *table, const char *name, void *data, bucket_t *buck)
void *Hash_AddInsensative(hashtable_t *table, const char *name, void *data, bucket_t *buck);
void Hash_Remove(hashtable_t *table, const char *name);
void Hash_RemoveData(hashtable_t *table, const char *name, void *data);
void Hash_RemoveBucket(hashtable_t *table, const char *name, bucket_t *data);
void Hash_RemoveKey(hashtable_t *table, unsigned int key);
void *Hash_AddKey(hashtable_t *table, unsigned int key, void *data, bucket_t *buck);

View file

@ -160,6 +160,38 @@ static void PF_fmem_unlink(progfuncs_t *pr, qcmemfreeblock_t *p)
np->prev = p->prev;
}
}
static void PR_memvalidate (progfuncs_t *progfuncs)
{
qcmemfreeblock_t *p;
qcmemusedblock_t *ub = NULL;
unsigned int b,l;
b = prinst->mfreelist;
l = 0;
while (b)
{
if (b < 0 || b >= prinst->addressableused)
{
printf("PF_memalloc: memory corruption\n");
PR_StackTrace(progfuncs);
return;
}
p = (qcmemfreeblock_t*)(progfuncs->stringtable + b);
if (p->prev != l ||
p->next && p->next < b + p->size ||
p->next >= prinst->addressableused ||
b + p->size >= prinst->addressableused ||
p->prev >= b)
{
printf("PF_memalloc: memory corruption\n");
PR_StackTrace(progfuncs);
return;
}
l = b;
b = p->next;
}
}
static void *PR_memalloc (progfuncs_t *progfuncs, unsigned int size)
{
qcmemfreeblock_t *p, *np;
@ -220,6 +252,7 @@ static void *PR_memalloc (progfuncs_t *progfuncs, unsigned int size)
}
break;
}
b = p->next;
}
/*assign more space*/
@ -236,19 +269,23 @@ static void *PR_memalloc (progfuncs_t *progfuncs, unsigned int size)
memset(ub, 0, size);
ub->marker = MARKER;
ub->size = size;
// PR_memvalidate(progfuncs);
return ub+1;
}
static void PR_memfree (progfuncs_t *progfuncs, void *memptr)
{
qcmemusedblock_t *ub;
qcmemfreeblock_t *p, *np;
unsigned int l, ln;
qcmemfreeblock_t *p, *np, *pp;
unsigned int pa, na; //prev addr, next addr
unsigned int size;
unsigned int ptr = memptr?((char*)memptr - progfuncs->stringtable):0;
/*freeing NULL is ignored*/
if (!ptr)
return;
// PR_memvalidate(progfuncs);
if (ptr < sizeof(qcmemusedblock_t) || ptr >= prinst->addressableused)
{
printf("PF_memfree: pointer invalid - out of range (%u >= %u)\n", ptr, prinst->addressableused);
@ -268,18 +305,18 @@ static void PR_memfree (progfuncs_t *progfuncs, void *memptr)
ub->marker = 0;
size = ub->size;
for (ln = prinst->mfreelist, l = 0; ;)
for (na = prinst->mfreelist, pa = 0; ;)
{
if (ln < 0 || ln >= prinst->addressableused)
if (na < 0 || na >= prinst->addressableused)
{
printf("PF_memfree: memory corruption\n");
PR_StackTrace(progfuncs);
return;
}
if (!ln || ln >= ptr)
if (!na || na >= ptr)
{
np = (qcmemfreeblock_t*)(progfuncs->stringtable + l);
if (l && l+np->size>ptr)
np = (qcmemfreeblock_t*)(progfuncs->stringtable + pa);
if (pa && pa+np->size>ptr)
{
printf("PF_memfree: double free\n");
PR_StackTrace(progfuncs);
@ -288,15 +325,17 @@ static void PR_memfree (progfuncs_t *progfuncs, void *memptr)
/*generate the free block, now we know its proper values*/
p = (qcmemfreeblock_t*)(progfuncs->stringtable + ptr);
p->prev = l;
p->next = ln;
np = na?(qcmemfreeblock_t*)(progfuncs->stringtable + na):NULL;
pp = pa?(qcmemfreeblock_t*)(progfuncs->stringtable + pa):NULL;
p->prev = pa;
p->next = na;
p->size = size;
/*update the next's previous*/
if (p->next)
if (na)
{
np = (qcmemfreeblock_t*)(progfuncs->stringtable + p->next);
np->prev = p->prev;
np->prev = ptr;
/*extend this block and kill the next if they are adjacent*/
if (p->next == ptr + size)
@ -307,27 +346,29 @@ static void PR_memfree (progfuncs_t *progfuncs, void *memptr)
}
/*update the link to get here*/
if (!l)
if (!pa)
prinst->mfreelist = ptr;
else
{
np = (qcmemfreeblock_t*)(progfuncs->stringtable + l);
np->next = ptr;
pp->next = ptr;
/*we're adjacent to the previous block, so merge them by killing the newly freed region*/
if (l + np->size == ptr)
if (na && pa + np->size == ptr)
{
np->size += size;
PF_fmem_unlink(progfuncs, p);
p->size += np->size;
PF_fmem_unlink(progfuncs, np);
}
}
break;
}
l = ln;
p = (qcmemfreeblock_t*)(progfuncs->stringtable + l);
ln = p->next;
pa = na;
p = (qcmemfreeblock_t*)(progfuncs->stringtable + pa);
na = p->next;
}
// PR_memvalidate(progfuncs);
}
void PRAddressableFlush(progfuncs_t *progfuncs, int totalammount)

View file

@ -6719,7 +6719,7 @@ void QCC_PR_ParseAsm(void)
QCC_PR_ParseError(ERR_BADOPCODE, "Bad op code name %s", pr_token);
}
pbool QCC_FuncJumpsTo(int first, int last, int statement)
static pbool QCC_FuncJumpsTo(int first, int last, int statement)
{
int st;
for (st = first; st < last; st++)
@ -6770,7 +6770,7 @@ pbool QCC_FuncJumpsTo(int first, int last, int statement)
return false;
}
pbool QCC_FuncJumpsToRange(int first, int last, int firstr, int lastr)
static pbool QCC_FuncJumpsToRange(int first, int last, int firstr, int lastr)
{
int st;
for (st = first; st < last; st++)

View file

@ -791,7 +791,13 @@ void NPP_NQFlush(void)
else
multicastpos = 0;
if (bufferlen)
{
if (writedest->cursize + bufferlen > writedest->maxsize)
{
SV_FlushBroadcasts();
}
SZ_Write(writedest, buffer, bufferlen);
}
if (multicastpos)
{

View file

@ -1138,8 +1138,6 @@ void PR_Init(void)
{
int i;
PF_Common_RegisterCvars();
Cmd_AddCommand ("breakpoint", PR_BreakPoint_f);
Cmd_AddCommand ("decompile", PR_Decompile_f);
Cmd_AddCommand ("compile", PR_Compile_f);
@ -4047,13 +4045,14 @@ PF_pointcontents
*/
static void QCBUILTIN PF_pointcontents (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
world_t *w = prinst->parms->user;
float *v;
int cont;
v = G_VECTOR(OFS_PARM0);
// cont = SV_Move(v, vec3_origin, vec3_origin, v, MOVE_NOMONSTERS, NULL).contents;
cont = World_PointContents (&sv.world, v);
cont = World_PointContents(w, v);
if (cont & FTECONTENTS_SOLID)
G_FLOAT(OFS_RETURN) = Q1CONTENTS_SOLID;
else if (cont & FTECONTENTS_SKY)
@ -8626,8 +8625,8 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"eprint", PF_eprint, 31, 31, 31, 0, "void(entity e)"},// debug print an entire entity
{"walkmove", PF_walkmove, 32, 32, 32, 0, "float(float yaw, float dist)"},
{"tracearea", PF_traceboxh2, 0, 0, 33, 0, "void(vector v1, vector v2, vector mins, vector maxs, float nomonsters, entity ent)"},
// {"qtest_flymove", NULL, 33}, // float(vector dir) flymove = #33;
//qbism super8's 'private'sound #33
{"droptofloor", PF_droptofloor, 34, 34, 34, 0, "float()"},
{"lightstyle", PF_lightstyle, 35, 35, 35, 0, "void(float lightstyle, string stylestring)"},
{"rint", PF_rint, 36, 36, 36, 0, "float(float)"},
@ -9799,6 +9798,7 @@ void PR_DumpPlatform_f(void)
#undef comfieldfunction
{"physics_mode", "var float", QW|NQ|CS, 2},
{"gamespeed", "float", CS},
{"TRUE", "const float", QW|NQ|CS, 1},
{"FALSE", "const float", QW|NQ|CS, 0},
@ -10204,7 +10204,6 @@ void PR_DumpPlatform_f(void)
VFS_CLOSE(f);
FS_FlushFSHash();
Con_Printf("Written \"%s\"\n", dbgfname);
#endif
}

View file

@ -502,7 +502,8 @@ void LoadModelsAndSounds(vfsfile_t *f)
*sv.strings.sound_precache[i] = 0;
}
qboolean SV_LoadLevelCache(char *savename, char *level, char *startspot, qboolean ignoreplayers)
/*ignoreplayers - says to not tell gamecode (a loadgame rather than a level change)*/
qboolean SV_LoadLevelCache(char *savename, char *level, char *startspot, qboolean isloadgame)
{
eval_t *eval, *e2;
@ -529,18 +530,25 @@ qboolean SV_LoadLevelCache(char *savename, char *level, char *startspot, qboolea
levelcache_t *cache;
cache = svs.levcache;
while(cache)
if (isloadgame)
{
if (!strcmp(cache->mapname, level))
break;
cache = cache->next;
gametype = svs.gametype;
}
if (!cache)
return false; //not visited yet. Ignore the existing caches as fakes.
else
{
cache = svs.levcache;
while(cache)
{
if (!strcmp(cache->mapname, level))
break;
gametype = cache->gametype;
cache = cache->next;
}
if (!cache)
return false; //not visited yet. Ignore the existing caches as fakes.
gametype = cache->gametype;
}
if (savename)
Q_snprintfz (name, sizeof(name), "saves/%s/%s", savename, level);
@ -696,16 +704,22 @@ qboolean SV_LoadLevelCache(char *savename, char *level, char *startspot, qboolea
for (i=0 ; i<MAX_CLIENTS ; i++)
{
ent = EDICT_NUM(svprogfuncs, i+1);
if (i < sv.allocated_client_slots)
ent = EDICT_NUM(svprogfuncs, i+1);
else
ent = NULL;
svs.clients[i].edict = ent;
svs.clients[i].name = PR_AddString(svprogfuncs, svs.clients[i].namebuf, sizeof(svs.clients[i].namebuf));
svs.clients[i].team = PR_AddString(svprogfuncs, svs.clients[i].teambuf, sizeof(svs.clients[i].teambuf));
svs.clients[i].playerclass = ent->xv->playerclass;
if (ent)
svs.clients[i].playerclass = ent->xv->playerclass;
else
svs.clients[i].playerclass = 0;
}
if (!ignoreplayers)
if (!isloadgame)
{
eval = PR_FindGlobal(svprogfuncs, "startspot", 0, NULL);
if (eval) eval->_int = (int)PR_NewString(svprogfuncs, startspot, 0);
@ -836,7 +850,7 @@ void SV_SaveLevelCache(char *savedir, qboolean dontharmgame)
if (!FS_NativePath(name, FS_GAMEONLY, syspath, sizeof(syspath)))
return;
ge->WriteLevel(syspath);
FS_FlushFSHash();
FS_FlushFSHashReally();
return;
}
#endif
@ -926,8 +940,6 @@ void SV_SaveLevelCache(char *savedir, qboolean dontharmgame)
svprogfuncs->parms->memfree(s);
VFS_CLOSE (f);
FS_FlushFSHash();
}
#ifdef NEWSAVEFORMAT
@ -1049,8 +1061,6 @@ void SV_Savegame (char *savename)
VFS_PRINTF (f, "%s\n", sv.name);
VFS_CLOSE(f);
FS_FlushFSHash();
}
void SV_Savegame_f (void)
@ -1245,6 +1255,7 @@ void SV_Loadgame_f (void)
VFS_CLOSE(f);
svs.gametype = gametype;
SV_LoadLevelCache(savename, str, "", true);
sv.allocated_client_slots = slots;
sv.spawned_client_slots += loadzombies;

View file

@ -1053,6 +1053,7 @@ void SV_Begin_Core(client_t *split);
void VoteFlushAll(void);
void SV_SetUpClientEdict (client_t *cl, edict_t *ent);
void SV_UpdateToReliableMessages (void);
void SV_FlushBroadcasts (void);
void SV_DarkPlacesDownloadChunk(client_t *cl, sizebuf_t *msg);
void SV_New_f (void);

View file

@ -510,6 +510,10 @@ void SV_Map_f (void)
}
#ifndef SERVERONLY
SCR_ImageName(level);
SCR_SetLoadingStage(LS_SERVER);
SCR_SetLoadingFile("finalize server");
#else
#define SCR_SetLoadingFile(s)
#endif
COM_FlushFSCache();
@ -630,12 +634,14 @@ void SV_Map_f (void)
}
SV_SendMessagesToAll ();
SCR_SetLoadingFile("spawnserver");
if (newunit || !startspot || cinematic || !SV_LoadLevelCache(NULL, level, startspot, false))
{
if (waschangelevel && !startspot)
startspot = "";
SV_SpawnServer (level, startspot, false, cinematic);
}
SCR_SetLoadingFile("server spawned");
//SV_BroadcastCommand ("cmd new\n");
for (i=0, host_client = svs.clients ; i<MAX_CLIENTS ; i++, host_client++)

View file

@ -291,9 +291,6 @@ void SV_SaveSpawnparms (qboolean dontsave)
if (host_client->state != cs_spawned)
continue;
// needs to reconnect
host_client->state = cs_connected;
if (dontsave) //level restart requires that stats can be reset
continue;
@ -756,6 +753,9 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
current_loading_size+=10;
//SCR_BeginLoadingPlaque();
SCR_ImageName(server);
SCR_SetLoadingFile("map");
#else
#define SCR_SetLoadingFile(s)
#endif
Cvar_ApplyLatches(CVAR_LATCH);
@ -819,12 +819,14 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
current_loading_size+=10;
// SCR_BeginLoadingPlaque();
SCR_ImageName(server);
SCR_SetLoadingFile("phs");
#endif
SV_CalcPHS ();
#ifndef SERVERONLY
current_loading_size+=10;
//SCR_BeginLoadingPlaque();
SCR_ImageName(server);
SCR_SetLoadingFile("gamecode");
#endif
if (sv.world.worldmodel->fromgame == fg_doom)
@ -1020,6 +1022,7 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
current_loading_size+=10;
//SCR_BeginLoadingPlaque();
SCR_ImageName(server);
SCR_SetLoadingFile("clients");
#endif
for (i=0 ; i<MAX_CLIENTS ; i++)
@ -1224,6 +1227,7 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
}
// load and spawn all other entities
SCR_SetLoadingFile("entities");
if (progstype == PROG_H2)
{
extern cvar_t coop;

View file

@ -4191,6 +4191,7 @@ void SV_InitLocal (void)
Cvar_Register (&sv_cullplayers_trace, cvargroup_servercontrol);
Cvar_Register (&sv_cullentities_trace, cvargroup_servercontrol);
Cvar_Register (&sv_csqc_progname, cvargroup_servercontrol);
Cvar_Register (&sv_csqcdebug, cvargroup_servercontrol);
Cvar_Register (&sv_gamespeed, cvargroup_serverphysics);
@ -4830,6 +4831,8 @@ void SV_Init (quakeparms_t *parms)
#endif
COM_Init ();
Mod_Init ();
PF_Common_RegisterCvars();
}
PR_Init ();
@ -4871,7 +4874,7 @@ void SV_Init (quakeparms_t *parms)
host_initialized = true;
//get rid of the worst of the spam
Cmd_AddRemCommand("bind", SV_IgnoreCommand_f);
Cmd_AddCommand("bind", SV_IgnoreCommand_f);
Con_TPrintf (TL_EXEDATETIME, __DATE__, __TIME__);
Con_TPrintf (TL_HEAPSIZE,parms->memsize/ (1024*1024.0));

View file

@ -1435,9 +1435,10 @@ mvddest_t *SV_InitRecordFile (char *name)
}
}
else
{
FS_Remove(path, FS_GAMEONLY);
FS_FlushFSHash();
FS_FlushFSHashRemoved();
}
return dst;
}

View file

@ -1875,6 +1875,74 @@ client_t *SV_SplitClientDest(client_t *client, qbyte first, int size)
return client;
}
}
void SV_FlushBroadcasts (void)
{
client_t *client;
int j;
// append the broadcast messages to each client messages
for (j=0, client = svs.clients ; j<MAX_CLIENTS ; j++, client++)
{
if (client->state < cs_connected)
continue; // reliables go to all connected or spawned
if (client->controller)
continue; //splitscreen
if (client->protocol == SCP_BAD)
continue; //botclient
#ifdef Q2SERVER
if (ISQ2CLIENT(client))
{
ClientReliableCheckBlock(client, sv.q2reliable_datagram.cursize);
ClientReliableWrite_SZ(client, sv.q2reliable_datagram.data, sv.q2reliable_datagram.cursize);
if (client->state != cs_spawned)
continue; // datagrams only go to spawned
SZ_Write (&client->datagram
, sv.q2datagram.data
, sv.q2datagram.cursize);
}
else
#endif
#ifdef NQPROT
if (!ISQWCLIENT(client))
{
if (client->pextknown)
{
ClientReliableCheckBlock(client, sv.nqreliable_datagram.cursize);
ClientReliableWrite_SZ(client, sv.nqreliable_datagram.data, sv.nqreliable_datagram.cursize);
}
if (client->state != cs_spawned)
continue; // datagrams only go to spawned
SZ_Write (&client->datagram
, sv.nqdatagram.data
, sv.nqdatagram.cursize);
}
else
#endif
{
ClientReliableCheckBlock(client, sv.reliable_datagram.cursize);
ClientReliableWrite_SZ(client, sv.reliable_datagram.data, sv.reliable_datagram.cursize);
if (client->state != cs_spawned)
continue; // datagrams only go to spawned
SZ_Write (&client->datagram
, sv.datagram.data
, sv.datagram.cursize);
}
}
SZ_Clear (&sv.reliable_datagram);
SZ_Clear (&sv.datagram);
#ifdef NQPROT
SZ_Clear (&sv.nqreliable_datagram);
SZ_Clear (&sv.nqdatagram);
#endif
SZ_Clear (&sv.q2reliable_datagram);
SZ_Clear (&sv.q2datagram);
}
/*
=======================
SV_UpdateToReliableMessages
@ -2090,67 +2158,7 @@ void SV_UpdateToReliableMessages (void)
SZ_Clear (&sv.q2datagram);
#endif
// append the broadcast messages to each client messages
for (j=0, client = svs.clients ; j<MAX_CLIENTS ; j++, client++)
{
if (client->state < cs_connected)
continue; // reliables go to all connected or spawned
if (client->controller)
continue; //splitscreen
if (client->protocol == SCP_BAD)
continue; //botclient
#ifdef Q2SERVER
if (ISQ2CLIENT(client))
{
ClientReliableCheckBlock(client, sv.q2reliable_datagram.cursize);
ClientReliableWrite_SZ(client, sv.q2reliable_datagram.data, sv.q2reliable_datagram.cursize);
if (client->state != cs_spawned)
continue; // datagrams only go to spawned
SZ_Write (&client->datagram
, sv.q2datagram.data
, sv.q2datagram.cursize);
}
else
#endif
#ifdef NQPROT
if (!ISQWCLIENT(client))
{
if (client->pextknown)
{
ClientReliableCheckBlock(client, sv.nqreliable_datagram.cursize);
ClientReliableWrite_SZ(client, sv.nqreliable_datagram.data, sv.nqreliable_datagram.cursize);
}
if (client->state != cs_spawned)
continue; // datagrams only go to spawned
SZ_Write (&client->datagram
, sv.nqdatagram.data
, sv.nqdatagram.cursize);
}
else
#endif
{
ClientReliableCheckBlock(client, sv.reliable_datagram.cursize);
ClientReliableWrite_SZ(client, sv.reliable_datagram.data, sv.reliable_datagram.cursize);
if (client->state != cs_spawned)
continue; // datagrams only go to spawned
SZ_Write (&client->datagram
, sv.datagram.data
, sv.datagram.cursize);
}
}
SZ_Clear (&sv.reliable_datagram);
SZ_Clear (&sv.datagram);
#ifdef NQPROT
SZ_Clear (&sv.nqreliable_datagram);
SZ_Clear (&sv.nqdatagram);
#endif
SZ_Clear (&sv.q2reliable_datagram);
SZ_Clear (&sv.q2datagram);
SV_FlushBroadcasts();
}
#ifdef _MSC_VER

View file

@ -3946,6 +3946,8 @@ void Cmd_Give_f (void)
case 'c':
sv_player->v->ammo_cells = v;
break;
default:
Con_Printf("give: unknown item\n");
}
}
else

View file

@ -6,6 +6,25 @@ char shaders[][64] =
"bloom_blur",
"bloom_filter",
"bloom_final",
"colourtint",
"crepuscular_opaque",
"crepuscular_rays",
"crepuscular_sky",
"default2d",
"defaultadditivesprite",
"defaultskin",
"defaultsky",
"defaultsprite",
"defaultwall",
"defaultwarp",
"drawflat_wall",
"lpp_depthnorm",
"lpp_light",
"lpp_wall",
"postproc_fisheye",
"postproc_panorama",
"rtlight",
"underwaterwarp",
""
};

View file

@ -0,0 +1,22 @@
//this glsl shader is useful for cubemapped post processing effects (see csaddon for an example)
varying vec4 tf;
#ifdef VERTEX_SHADER
void main ()
{
gl_Position = tf = vec4(v_position.xy,-1.0, 1.0);
}
#endif
#ifdef FRAGMENT_SHADER
uniform sampler2D s_t0;
uniform sampler3D s_t1;
void main()
{
vec2 fc;
fc = tf.xy / tf.w;
vec3 raw = texture2D(s_t0, (1.0 + fc) / 2.0).rgb;
#define LUTSIZE 16.0
vec3 scale = vec3((LUTSIZE-1.0)/LUTSIZE);
vec3 bias = vec3(1.0/(2.0*LUTSIZE));
gl_FragColor = texture3D(s_t1, raw * scale + bias);
}
#endif

View file

@ -0,0 +1,13 @@
//opaque surfaces are drawn to the render target to mask out skies
#ifdef VERTEX_SHADER
void main ()
{
gl_Position = ftetransform();
}
#endif
#ifdef FRAGMENT_SHADER
void main()
{
gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
}
#endif

View file

@ -0,0 +1,43 @@
!!cvarf crep_decay
!!cvarf crep_density
!!cvarf crep_weight
//this is a post-processing shader, drawn in 2d
//there will be a render target containing sky surfaces drawn with crepuscular_sky, and everything else drawn with crepuscular_opaque (to mask out the sky)
//this shader then just smudges the sky out a bit as though its coming from the sun or whatever through the clouds.
//yoinked from http://fabiensanglard.net/lightScattering/index.php
varying vec2 tc;
#ifdef VERTEX_SHADER
attribute vec2 v_texcoord;
void main ()
{
tc = v_texcoord;
gl_Position = v_position;
}
#endif
#ifdef FRAGMENT_SHADER
const float crep_decay = 0.94;
const float crep_density = 0.5;
const float crep_weight = 0.2;
uniform vec3 l_lightcolour;
uniform vec3 l_lightscreen;
uniform sampler2D s_t0;
const int NUM_SAMPLES = 100;
void main()
{
vec2 deltaTextCoord = vec2(tc.st - l_lightscreen.xy);
vec2 textCoo = tc.st;
deltaTextCoord *= 1.0 / float(NUM_SAMPLES) * crep_density;
float illuminationDecay = 1.0;
for(int i=0; i < NUM_SAMPLES ; i++)
{
textCoo -= deltaTextCoord;
vec4 sample = texture2D(s_t0, textCoo);
sample *= illuminationDecay * crep_weight;
gl_FragColor += sample;
illuminationDecay *= crep_decay;
}
gl_FragColor *= vec4(l_lightcolour, 1.0);
}
#endif

View file

@ -0,0 +1,31 @@
//pretty much a regular sky shader
//though in reality we should render a sun circle in the middle.
//still, its kinda cool to have scrolling clouds masking out parts of the sun.
#ifdef VERTEX_SHADER
varying vec3 pos;
void main ()
{
pos = v_position.xyz;
gl_Position = ftetransform();
}
#endif
#ifdef FRAGMENT_SHADER
uniform float e_time;
uniform vec3 e_eyepos;
varying vec3 pos;
uniform sampler2D s_t0;
uniform sampler2D s_t1;
void main ()
{
vec2 tccoord;
vec3 dir = pos - e_eyepos;
dir.z *= 3.0;
dir.xy /= 0.5*length(dir);
tccoord = (dir.xy + e_time*0.03125);
vec3 solid = vec3(texture2D(s_t0, tccoord));
tccoord = (dir.xy + e_time*0.0625);
vec4 clouds = texture2D(s_t1, tccoord);
gl_FragColor.rgb = (solid.rgb*(1.0-clouds.a)) + (clouds.a*clouds.rgb);
}
#endif

View file

@ -0,0 +1,26 @@
//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
attribute vec2 v_texcoord;
attribute vec4 v_colour;
varying vec2 tc;
varying vec4 vc;
void main ()
{
tc = v_texcoord;
vc = v_colour;
gl_Position = ftetransform();
}
#endif
#ifdef FRAGMENT_SHADER
uniform sampler2D s_t0;
in vec2 tc;
varying vec4 vc;
void main ()
{
gl_FragColor = texture2D(s_t0, tc) * vc;
}
#endif

View file

@ -0,0 +1,28 @@
!!permu FOG
//meant to be used for additive stuff. presumably particles and sprites. though actually its only flashblend effects that use this at the time of writing.
//includes fog, apparently.
#include "sys/fog.h"
#ifdef VERTEX_SHADER
attribute vec2 v_texcoord;
attribute vec4 v_colour;
varying vec2 tc;
varying vec4 vc;
void main ()
{
tc = v_texcoord;
vc = v_colour;
gl_Position = ftetransform();
}
#endif
#ifdef FRAGMENT_SHADER
uniform sampler2D s_t0;
varying vec2 tc;
varying vec4 vc;
uniform vec4 e_colourident;
void main ()
{
gl_FragColor = fog4additive(texture2D(s_t0, tc) * vc * e_colourident);
}
#endif

View file

@ -0,0 +1,61 @@
!!permu FULLBRIGHT
!!permu UPPERLOWER
!!permu FRAMEBLEND
!!permu SKELETAL
!!permu FOG
//standard shader used for models.
//must support skeletal and 2-way vertex blending or Bad Things Will Happen.
//the vertex shader is responsible for calculating lighting values.
varying vec2 tc;
varying vec3 light;
#ifdef VERTEX_SHADER
#include "sys/skeletal.h"
attribute vec2 v_texcoord;
uniform vec3 e_light_dir;
uniform vec3 e_light_mul;
uniform vec3 e_light_ambient;
void main ()
{
vec3 n;
gl_Position = skeletaltransform_n(n);
light = e_light_ambient + (dot(n,e_light_dir)*e_light_mul);
tc = v_texcoord;
}
#endif
#ifdef FRAGMENT_SHADER
#include "sys/fog.h"
uniform sampler2D s_t0;
#ifdef LOWER
uniform sampler2D s_t1;
uniform vec3 e_lowercolour;
#endif
#ifdef UPPER
uniform sampler2D s_t2;
uniform vec3 e_uppercolour;
#endif
#ifdef FULLBRIGHT
uniform sampler2D s_t3;
#endif
uniform vec4 e_colourident;
void main ()
{
vec4 col, sp;
col = texture2D(s_t0, tc);
#ifdef UPPER
vec4 uc = texture2D(s_t2, tc);
col.rgb = mix(col.rgb, uc.rgb*e_uppercolour, uc.a);
#endif
#ifdef LOWER
vec4 lc = texture2D(s_t1, tc);
col.rgb = mix(col.rgb, lc.rgb*e_lowercolour, lc.a);
#endif
col.rgb *= light;
#ifdef FULLBRIGHT
vec4 fb = texture2D(s_t3, tc);
col.rgb = mix(col.rgb, fb.rgb, fb.a);
#endif
gl_FragColor = fog4(col * e_colourident);
}
#endif

View file

@ -0,0 +1,30 @@
//regular sky shader for scrolling q1 skies
//the sky surfaces are thrown through this as-is.
#ifdef VERTEX_SHADER
varying vec3 pos;
void main ()
{
pos = v_position.xyz;
gl_Position = ftetransform();
}
#endif
#ifdef FRAGMENT_SHADER
uniform float e_time;
uniform vec3 e_eyepos;
varying vec3 pos;
uniform sampler2D s_t0;
uniform sampler2D s_t1;
void main ()
{
vec2 tccoord;
vec3 dir = pos - e_eyepos;
dir.z *= 3.0;
dir.xy /= 0.5*length(dir);
tccoord = (dir.xy + e_time*0.03125);
vec3 solid = vec3(texture2D(s_t0, tccoord));
tccoord = (dir.xy + e_time*0.0625);
vec4 clouds = texture2D(s_t1, tccoord);
gl_FragColor.rgb = (solid.rgb*(1.0-clouds.a)) + (clouds.a*clouds.rgb);
}
#endif

View file

@ -0,0 +1,27 @@
!!permu FOG
//used by both particles and sprites.
//note the fog blending mode is all that differs from defaultadditivesprite
#include "sys/fog.h"
#ifdef VERTEX_SHADER
attribute vec2 v_texcoord;
attribute vec4 v_colour;
varying vec2 tc;
varying vec4 vc;
void main ()
{
tc = v_texcoord;
vc = v_colour;
gl_Position = ftetransform();
}
#endif
#ifdef FRAGMENT_SHADER
uniform sampler2D s_t0;
varying vec2 tc;
varying vec4 vc;
uniform vec4 e_colourident;
void main ()
{
gl_FragColor = fog4blend(texture2D(s_t0, tc) * vc * e_colourident);
}
#endif

View file

@ -0,0 +1,66 @@
!!permu OFFSETMAPPING
!!permu FULLBRIGHT
!!permu FOG
!!cvarf r_glsl_offsetmapping_scale
//this is what normally draws all of your walls, even with rtlights disabled
//note that the '286' preset uses drawflat_walls instead.
#include "sys/fog.h"
#if defined(OFFSETMAPPING)
varying vec3 eyevector;
#endif
#ifdef VERTEX_SHADER
attribute vec2 v_texcoord;
attribute vec2 v_lmcoord;
varying vec2 tc, lm;
#if defined(OFFSETMAPPING)
uniform vec3 e_eyepos;
attribute vec3 v_normal;
attribute vec3 v_svector;
attribute vec3 v_tvector;
#endif
void main ()
{
#if defined(OFFSETMAPPING)
vec3 eyeminusvertex = e_eyepos - v_position.xyz;
eyevector.x = dot(eyeminusvertex, v_svector.xyz);
eyevector.y = -dot(eyeminusvertex, v_tvector.xyz);
eyevector.z = dot(eyeminusvertex, v_normal.xyz);
#endif
tc = v_texcoord;
lm = v_lmcoord;
gl_Position = ftetransform();
}
#endif
#ifdef FRAGMENT_SHADER
uniform sampler2D s_t0;
uniform sampler2D s_t1;
#ifdef OFFSETMAPPING
uniform sampler2D s_t2;
#endif
#ifdef FULLBRIGHT
uniform sampler2D s_t4;
#endif
varying vec2 tc, lm;
uniform vec4 e_lmscale;
uniform vec4 e_colourident;
#ifdef OFFSETMAPPING
#include "sys/offsetmapping.h"
#endif
void main ()
{
#ifdef OFFSETMAPPING
vec2 tcoffsetmap = offsetmap(s_t2, tc, eyevector);
#define tc tcoffsetmap
#endif
gl_FragColor = texture2D(s_t0, tc) * texture2D(s_t1, lm) * e_lmscale;
#ifdef FULLBRIGHT
gl_FragColor.rgb += texture2D(s_t4, tc).rgb;
#endif
gl_FragColor = gl_FragColor * e_colourident;
#ifdef FOG
gl_FragColor = fog4(gl_FragColor);
#endif
}
#endif

View file

@ -0,0 +1,29 @@
!!cvarf r_wateralpha
!!permu FOG
//this is the shader that's responsible for drawing default q1 turbulant water surfaces
//this is expected to be moderately fast.
#include "sys/fog.h"
varying vec2 tc;
#ifdef VERTEX_SHADER
attribute vec2 v_texcoord;
void main ()
{
tc = v_texcoord.st;
gl_Position = ftetransform();
}
#endif
#ifdef FRAGMENT_SHADER
uniform sampler2D s_t0;
uniform float e_time;
uniform float cvar_r_wateralpha;
void main ()
{
vec2 ntc;
ntc.s = tc.s + sin(tc.t+e_time)*0.125;
ntc.t = tc.t + sin(tc.s+e_time)*0.125;
vec3 ts = vec3(texture2D(s_t0, ntc));
gl_FragColor = fog4(vec4(ts, cvar_r_wateralpha));
}
#endif

View file

@ -0,0 +1,30 @@
!!cvarv r_floorcolor
!!cvarv r_wallcolor
!!permu FOG
//this is for the '286' preset walls, and just draws lightmaps coloured based upon surface normals.
#include "sys/fog.h"
varying vec4 col;
#ifdef VERTEX_SHADER
attribute vec3 v_normal;
attribute vec2 v_lmcoord;
varying vec2 lm;
uniform vec3 cvar_r_wallcolor;
uniform vec3 cvar_r_floorcolor;
uniform vec4 e_lmscale;
void main ()
{
col = vec4(e_lmscale.rgb/255.0 * ((v_normal.z < 0.73)?cvar_r_wallcolor:cvar_r_floorcolor), e_lmscale.a);
lm = v_lmcoord;
gl_Position = ftetransform();
}
#endif
#ifdef FRAGMENT_SHADER
uniform sampler2D s_t0;
varying vec2 lm;
void main ()
{
gl_FragColor = fog4(col * texture2D(s_t0, lm));
}
#endif

View file

@ -0,0 +1,39 @@
!!permu BUMP
!!permu SKELETAL
//light pre-pass rendering (defered lighting)
//this is the initial pass, that draws the surface normals and depth to the initial colour buffer
varying vec3 norm, tang, bitang;
#if defined(BUMP)
varying vec2 tc;
#endif
#ifdef VERTEX_SHADER
#include "sys/skeletal.h"
attribute vec2 v_texcoord;
void main()
{
#if defined(BUMP)
gl_Position = skeletaltransform_nst(norm, tang, bitang);
tc = v_texcoord;
#else
gl_Position = skeletaltransform_n(norm);
#endif
}
#endif
#ifdef FRAGMENT_SHADER
#if defined(BUMP)
uniform sampler2D s_t0;
#endif
void main()
{
vec3 onorm;
#if defined(BUMP)
vec3 bm = 2.0*texture2D(s_t0, tc).xyz - 1.0;
onorm = normalize(bm.x * tang + bm.y * bitang + bm.z * norm);
#else
onorm = norm;
#endif
gl_FragColor = vec4(onorm.xyz, gl_FragCoord.z / gl_FragCoord.w);
}
#endif

View file

@ -0,0 +1,58 @@
//this shader is a light shader. ideally drawn with a quad covering the entire region
//the output is contribution from this light (which will be additively blended)
//you can blame Electro for much of the maths in here.
//fixme: no fog
varying vec4 tf;
#ifdef VERTEX_SHADER
void main()
{
tf = ftetransform();
gl_Position = tf;
}
#endif
#ifdef FRAGMENT_SHADER
uniform sampler2D s_t0;
uniform vec3 l_lightposition;
uniform mat4 m_invviewprojection;
uniform vec3 l_lightcolour;
uniform float l_lightradius;
vec3 calcLightWorldPos(vec2 screenPos, float depth)
{
vec4 pos;
pos.x = screenPos.x;
pos.y = screenPos.y;
pos.z = depth;
pos.w = 1.0;
pos = m_invviewprojection * pos;
return pos.xyz / pos.w;
}
void main ()
{
vec3 lightColour = l_lightcolour.rgb;
float lightIntensity = 1.0;
float lightAttenuation = l_lightradius; // fixme: just use the light radius for now, use better near/far att math separately once working
float radiusFar = l_lightradius;
float radiusNear = l_lightradius*0.5;
vec2 fc;
fc = tf.xy / tf.w;
vec4 data = texture2D(s_t0, (1.0 + fc) / 2.0);
float depth = data.a;
vec3 norm = data.xyz;
/* calc where the wall that generated this sample came from */
vec3 worldPos = calcLightWorldPos(fc, depth);
/*calc diffuse lighting term*/
vec3 lightDir = l_lightposition - worldPos;
float zdiff = 1.0 - clamp(length(lightDir) / lightAttenuation, 0.0, 1.0);
float atten = (radiusFar * zdiff) / (radiusFar - radiusNear);
atten = pow(atten, 2.0);
lightDir = normalize(lightDir);
float nDotL = dot(norm, lightDir) * atten;
float lightDiffuse = max(0.0, nDotL);
gl_FragColor = vec4(lightDiffuse * (lightColour * lightIntensity), 1.0);
}
#endif

View file

@ -0,0 +1,34 @@
//the final defered lighting pass.
//the lighting values were written to some render target, which is fed into this shader, and now we draw all the wall textures with it.
varying vec2 tc, lm;
varying vec4 tf;
#ifdef VERTEX_SHADER
attribute vec2 v_texcoord;
attribute vec2 v_lmcoord;
void main ()
{
tc = v_texcoord;
lm = v_lmcoord;
gl_Position = tf = ftetransform();
}
#endif
#ifdef FRAGMENT_SHADER
uniform sampler2D s_t0;
uniform sampler2D s_t1;
uniform sampler2D s_t2;
uniform vec4 e_lmscale;
void main ()
{
vec2 nst;
nst = tf.xy / tf.w;
nst = (1.0 + nst) / 2.0;
vec4 l = texture2D(s_t0, nst)*5.0;
vec4 c = texture2D(s_t1, tc);
vec3 lmsamp = texture2D(s_t2, lm).rgb*lmscale;
vec3 diff = l.rgb;
vec3 chrom = diff / (0.001 + dot(diff, vec3(0.3, 0.59, 0.11)));
vec3 spec = chrom * l.a;
gl_FragColor = vec4((diff + lmsamp) * c.xyz, 1.0);
}
#endif

Some files were not shown because too many files have changed in this diff Show more