mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-29 07:02:12 +00:00
r_wireframe. requires cheats.
omni shadowmaps should work, but do still have issues. added colour tints to terrain, and clipped decals. fixed issue where fixed-function shaders were getting drawn with the glsl rendering functions. tweeked mvd recording code a little. don't use until next mvd-related commit. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4100 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
7135c3ee19
commit
197f716f75
34 changed files with 1360 additions and 714 deletions
|
@ -116,12 +116,10 @@ static void CL_ClearDlight(dlight_t *dl, int key)
|
|||
{
|
||||
void *sm;
|
||||
texid_t st;
|
||||
TEXASSIGNF(st, dl->stexture);
|
||||
sm = dl->worldshadowmesh;
|
||||
memset (dl, 0, sizeof(*dl));
|
||||
dl->rebuildcache = true;
|
||||
dl->worldshadowmesh = sm;
|
||||
TEXASSIGNF(dl->stexture, st);
|
||||
dl->axis[0][0] = 1;
|
||||
dl->axis[1][1] = 1;
|
||||
dl->axis[2][2] = 1;
|
||||
|
@ -873,10 +871,10 @@ void CL_ParsePacketEntities (qboolean delta)
|
|||
|
||||
if (cls.protocol == CP_QUAKEWORLD && cls.demoplayback == DPB_MVD)
|
||||
{
|
||||
extern float nextdemotime;
|
||||
extern float olddemotime; //time from the most recent demo packet
|
||||
cl.oldgametime = cl.gametime;
|
||||
cl.oldgametimemark = cl.gametimemark;
|
||||
cl.gametime = nextdemotime;
|
||||
cl.gametime = olddemotime;
|
||||
cl.gametimemark = realtime;
|
||||
}
|
||||
else if (!(cls.fteprotocolextensions & PEXT_ACCURATETIMINGS) && cls.protocol == CP_QUAKEWORLD)
|
||||
|
@ -2872,6 +2870,8 @@ void CL_LinkPacketEntities (void)
|
|||
// angles[1] += sin(realtime)*8;
|
||||
// angles[0] += cos(realtime*1.13)*5;
|
||||
AngleVectors(angles, dl->axis[0], dl->axis[1], dl->axis[2]);
|
||||
|
||||
VectorMA(dl->origin, 16, dl->axis[0], dl->origin);
|
||||
}
|
||||
|
||||
// add automatic particle trails
|
||||
|
@ -4146,7 +4146,7 @@ void CL_SetUpPlayerPrediction(qboolean dopred)
|
|||
if (playertime > realtime)
|
||||
playertime = realtime;
|
||||
|
||||
if (cl_nopred.value || /*cls.demoplayback ||*/ cl.paused)
|
||||
if (cl_nopred.value || /*cls.demoplayback ||*/ cl.paused || cl.worldmodel->needload)
|
||||
return;
|
||||
|
||||
frame = &cl.frames[cl.parsecount&UPDATE_MASK];
|
||||
|
|
|
@ -665,7 +665,10 @@ void CL_CalcClientTime(void)
|
|||
max = cl.gametime;
|
||||
min = cl.oldgametime;
|
||||
|
||||
cl.servertime += host_frametime;
|
||||
if (max)
|
||||
cl.servertime += host_frametime;
|
||||
else
|
||||
cl.servertime = 0;
|
||||
|
||||
if (cl.servertime > max)
|
||||
{
|
||||
|
|
|
@ -2282,10 +2282,8 @@ void SCR_DrawTwoDimensional(int uimenu, qboolean nohud)
|
|||
//
|
||||
// draw any areas not covered by the refresh
|
||||
//
|
||||
#ifdef GLQUAKE
|
||||
if (r_netgraph.value && qrenderer == QR_OPENGL)
|
||||
if (r_netgraph.value)
|
||||
GLR_NetGraph ();
|
||||
#endif
|
||||
|
||||
if (scr_drawloading || loading_stage)
|
||||
{
|
||||
|
|
|
@ -274,7 +274,6 @@ typedef struct dlight_s
|
|||
//the following are used for rendering (client code should clear on create)
|
||||
qboolean rebuildcache;
|
||||
struct shadowmesh_s *worldshadowmesh;
|
||||
texid_t stexture;
|
||||
texid_t cubetexture;
|
||||
struct {
|
||||
float updatetime;
|
||||
|
|
|
@ -887,6 +887,8 @@ void CLQ3_SendCmd(usercmd_t *cmd)
|
|||
ccs.serverTime = ccs.snap.serverTime + (Sys_Milliseconds()-ccs.snap.localTime);
|
||||
cl.servertime = ccs.serverTime / 1000.0f;
|
||||
|
||||
cl.gametime = cl.oldgametime = cl.servertime;
|
||||
|
||||
//reuse the q1 array
|
||||
cmd->servertime = ccs.serverTime;
|
||||
cmd->weapon = ccs.selected_weapon;
|
||||
|
|
|
@ -3119,6 +3119,422 @@ void TTS_Say_f(void)
|
|||
{
|
||||
TTS_SayAsciiString(Cmd_Args());
|
||||
}
|
||||
|
||||
#define ISpRecognizer void
|
||||
#define SPPHRASE void
|
||||
#define SPSERIALIZEDPHRASE void
|
||||
#define SPSTATEHANDLE void*
|
||||
#define SPGRAMMARWORDTYPE int
|
||||
#define SPPROPERTYINFO void
|
||||
#define SPLOADOPTIONS void*
|
||||
#define SPBINARYGRAMMAR void*
|
||||
#define SPRULESTATE int
|
||||
#define SPTEXTSELECTIONINFO void
|
||||
#define SPWORDPRONOUNCEABLE void
|
||||
#define SPGRAMMARSTATE int
|
||||
typedef struct ISpRecoResult ISpRecoResult;
|
||||
typedef struct ISpRecoContext ISpRecoContext;
|
||||
typedef struct ISpRecoGrammar ISpRecoGrammar;
|
||||
|
||||
typedef struct ISpRecoContextVtbl
|
||||
{
|
||||
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||
ISpRecoContext * This,
|
||||
/* [in] */ REFIID riid,
|
||||
/* [iid_is][out] */ void **ppvObject);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||
ISpRecoContext * This);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||
ISpRecoContext * This);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *SetNotifySink )(
|
||||
ISpRecoContext * This,
|
||||
/* [in] */ ISpNotifySink *pNotifySink);
|
||||
|
||||
/* [local] */ HRESULT ( STDMETHODCALLTYPE *SetNotifyWindowMessage )(
|
||||
ISpRecoContext * This,
|
||||
/* [in] */ HWND hWnd,
|
||||
/* [in] */ UINT Msg,
|
||||
/* [in] */ WPARAM wParam,
|
||||
/* [in] */ LPARAM lParam);
|
||||
|
||||
/* [local] */ HRESULT ( STDMETHODCALLTYPE *SetNotifyCallbackFunction )(
|
||||
ISpRecoContext * This,
|
||||
/* [in] */ SPNOTIFYCALLBACK *pfnCallback,
|
||||
/* [in] */ WPARAM wParam,
|
||||
/* [in] */ LPARAM lParam);
|
||||
|
||||
/* [local] */ HRESULT ( STDMETHODCALLTYPE *SetNotifyCallbackInterface )(
|
||||
ISpRecoContext * This,
|
||||
/* [in] */ ISpNotifyCallback *pSpCallback,
|
||||
/* [in] */ WPARAM wParam,
|
||||
/* [in] */ LPARAM lParam);
|
||||
|
||||
/* [local] */ HRESULT ( STDMETHODCALLTYPE *SetNotifyWin32Event )(
|
||||
ISpRecoContext * This);
|
||||
|
||||
/* [local] */ HRESULT ( STDMETHODCALLTYPE *WaitForNotifyEvent )(
|
||||
ISpRecoContext * This,
|
||||
/* [in] */ DWORD dwMilliseconds);
|
||||
|
||||
/* [local] */ HANDLE ( STDMETHODCALLTYPE *GetNotifyEventHandle )(
|
||||
ISpRecoContext * This);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *SetInterest )(
|
||||
ISpRecoContext * This,
|
||||
/* [in] */ ULONGLONG ullEventInterest,
|
||||
/* [in] */ ULONGLONG ullQueuedInterest);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetEvents )(
|
||||
ISpRecoContext * This,
|
||||
/* [in] */ ULONG ulCount,
|
||||
/* [size_is][out] */ SPEVENT *pEventArray,
|
||||
/* [out] */ ULONG *pulFetched);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetInfo )(
|
||||
ISpRecoContext * This,
|
||||
/* [out] */ SPEVENTSOURCEINFO *pInfo);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetRecognizer )(
|
||||
ISpRecoContext * This,
|
||||
/* [out] */ ISpRecognizer **ppRecognizer);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *CreateGrammar )(
|
||||
ISpRecoContext * This,
|
||||
/* [in] */ ULONGLONG ullGrammarId,
|
||||
/* [out] */ ISpRecoGrammar **ppGrammar);
|
||||
} ISpRecoContextVtbl;
|
||||
struct ISpRecoContext
|
||||
{
|
||||
struct ISpRecoContextVtbl *lpVtbl;
|
||||
};
|
||||
|
||||
typedef struct ISpRecoResultVtbl
|
||||
{
|
||||
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||
ISpRecoResult * This,
|
||||
/* [in] */ REFIID riid,
|
||||
/* [iid_is][out] */ void **ppvObject);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||
ISpRecoResult * This);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||
ISpRecoResult * This);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetPhrase )(
|
||||
ISpRecoResult * This,
|
||||
/* [out] */ SPPHRASE **ppCoMemPhrase);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetSerializedPhrase )(
|
||||
ISpRecoResult * This,
|
||||
/* [out] */ SPSERIALIZEDPHRASE **ppCoMemPhrase);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetText )(
|
||||
ISpRecoResult * This,
|
||||
/* [in] */ ULONG ulStart,
|
||||
/* [in] */ ULONG ulCount,
|
||||
/* [in] */ BOOL fUseTextReplacements,
|
||||
/* [out] */ WCHAR **ppszCoMemText,
|
||||
/* [out] */ BYTE *pbDisplayAttributes);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *Discard )(
|
||||
ISpRecoResult * This,
|
||||
/* [in] */ DWORD dwValueTypes);
|
||||
#if 0
|
||||
HRESULT ( STDMETHODCALLTYPE *GetResultTimes )(
|
||||
ISpRecoResult * This,
|
||||
/* [out] */ SPRECORESULTTIMES *pTimes);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetAlternates )(
|
||||
ISpRecoResult * This,
|
||||
/* [in] */ ULONG ulStartElement,
|
||||
/* [in] */ ULONG cElements,
|
||||
/* [in] */ ULONG ulRequestCount,
|
||||
/* [out] */ ISpPhraseAlt **ppPhrases,
|
||||
/* [out] */ ULONG *pcPhrasesReturned);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetAudio )(
|
||||
ISpRecoResult * This,
|
||||
/* [in] */ ULONG ulStartElement,
|
||||
/* [in] */ ULONG cElements,
|
||||
/* [out] */ ISpStreamFormat **ppStream);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *SpeakAudio )(
|
||||
ISpRecoResult * This,
|
||||
/* [in] */ ULONG ulStartElement,
|
||||
/* [in] */ ULONG cElements,
|
||||
/* [in] */ DWORD dwFlags,
|
||||
/* [out] */ ULONG *pulStreamNumber);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *Serialize )(
|
||||
ISpRecoResult * This,
|
||||
/* [out] */ SPSERIALIZEDRESULT **ppCoMemSerializedResult);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *ScaleAudio )(
|
||||
ISpRecoResult * This,
|
||||
/* [in] */ const GUID *pAudioFormatId,
|
||||
/* [in] */ const WAVEFORMATEX *pWaveFormatEx);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetRecoContext )(
|
||||
ISpRecoResult * This,
|
||||
/* [out] */ ISpRecoContext **ppRecoContext);
|
||||
|
||||
#endif
|
||||
} ISpRecoResultVtbl;
|
||||
struct ISpRecoResult
|
||||
{
|
||||
struct ISpRecoResultVtbl *lpVtbl;
|
||||
};
|
||||
|
||||
typedef struct ISpRecoGrammarVtbl
|
||||
{
|
||||
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||
ISpRecoGrammar * This,
|
||||
/* [in] */ REFIID riid,
|
||||
/* [iid_is][out] */ void **ppvObject);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||
ISpRecoGrammar * This);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||
ISpRecoGrammar * This);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *ResetGrammar )(
|
||||
ISpRecoGrammar * This,
|
||||
/* [in] */ WORD NewLanguage);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetRule )(
|
||||
ISpRecoGrammar * This,
|
||||
/* [in] */ const WCHAR *pszRuleName,
|
||||
/* [in] */ DWORD dwRuleId,
|
||||
/* [in] */ DWORD dwAttributes,
|
||||
/* [in] */ BOOL fCreateIfNotExist,
|
||||
/* [out] */ SPSTATEHANDLE *phInitialState);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *ClearRule )(
|
||||
ISpRecoGrammar * This,
|
||||
SPSTATEHANDLE hState);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *CreateNewState )(
|
||||
ISpRecoGrammar * This,
|
||||
SPSTATEHANDLE hState,
|
||||
SPSTATEHANDLE *phState);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *AddWordTransition )(
|
||||
ISpRecoGrammar * This,
|
||||
SPSTATEHANDLE hFromState,
|
||||
SPSTATEHANDLE hToState,
|
||||
const WCHAR *psz,
|
||||
const WCHAR *pszSeparators,
|
||||
SPGRAMMARWORDTYPE eWordType,
|
||||
float Weight,
|
||||
const SPPROPERTYINFO *pPropInfo);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *AddRuleTransition )(
|
||||
ISpRecoGrammar * This,
|
||||
SPSTATEHANDLE hFromState,
|
||||
SPSTATEHANDLE hToState,
|
||||
SPSTATEHANDLE hRule,
|
||||
float Weight,
|
||||
const SPPROPERTYINFO *pPropInfo);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *AddResource )(
|
||||
ISpRecoGrammar * This,
|
||||
/* [in] */ SPSTATEHANDLE hRuleState,
|
||||
/* [in] */ const WCHAR *pszResourceName,
|
||||
/* [in] */ const WCHAR *pszResourceValue);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *Commit )(
|
||||
ISpRecoGrammar * This,
|
||||
DWORD dwReserved);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetGrammarId )(
|
||||
ISpRecoGrammar * This,
|
||||
/* [out] */ ULONGLONG *pullGrammarId);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetRecoContext )(
|
||||
ISpRecoGrammar * This,
|
||||
/* [out] */ ISpRecoContext **ppRecoCtxt);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *LoadCmdFromFile )(
|
||||
ISpRecoGrammar * This,
|
||||
/* [string][in] */ const WCHAR *pszFileName,
|
||||
/* [in] */ SPLOADOPTIONS Options);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *LoadCmdFromObject )(
|
||||
ISpRecoGrammar * This,
|
||||
/* [in] */ REFCLSID rcid,
|
||||
/* [string][in] */ const WCHAR *pszGrammarName,
|
||||
/* [in] */ SPLOADOPTIONS Options);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *LoadCmdFromResource )(
|
||||
ISpRecoGrammar * This,
|
||||
/* [in] */ HMODULE hModule,
|
||||
/* [string][in] */ const WCHAR *pszResourceName,
|
||||
/* [string][in] */ const WCHAR *pszResourceType,
|
||||
/* [in] */ WORD wLanguage,
|
||||
/* [in] */ SPLOADOPTIONS Options);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *LoadCmdFromMemory )(
|
||||
ISpRecoGrammar * This,
|
||||
/* [in] */ const SPBINARYGRAMMAR *pGrammar,
|
||||
/* [in] */ SPLOADOPTIONS Options);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *LoadCmdFromProprietaryGrammar )(
|
||||
ISpRecoGrammar * This,
|
||||
/* [in] */ REFGUID rguidParam,
|
||||
/* [string][in] */ const WCHAR *pszStringParam,
|
||||
/* [in] */ const void *pvDataPrarm,
|
||||
/* [in] */ ULONG cbDataSize,
|
||||
/* [in] */ SPLOADOPTIONS Options);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *SetRuleState )(
|
||||
ISpRecoGrammar * This,
|
||||
/* [string][in] */ const WCHAR *pszName,
|
||||
void *pReserved,
|
||||
/* [in] */ SPRULESTATE NewState);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *SetRuleIdState )(
|
||||
ISpRecoGrammar * This,
|
||||
/* [in] */ ULONG ulRuleId,
|
||||
/* [in] */ SPRULESTATE NewState);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *LoadDictation )(
|
||||
ISpRecoGrammar * This,
|
||||
/* [string][in] */ const WCHAR *pszTopicName,
|
||||
/* [in] */ SPLOADOPTIONS Options);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *UnloadDictation )(
|
||||
ISpRecoGrammar * This);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *SetDictationState )(
|
||||
ISpRecoGrammar * This,
|
||||
/* [in] */ SPRULESTATE NewState);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *SetWordSequenceData )(
|
||||
ISpRecoGrammar * This,
|
||||
/* [in] */ const WCHAR *pText,
|
||||
/* [in] */ ULONG cchText,
|
||||
/* [in] */ const SPTEXTSELECTIONINFO *pInfo);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *SetTextSelection )(
|
||||
ISpRecoGrammar * This,
|
||||
/* [in] */ const SPTEXTSELECTIONINFO *pInfo);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *IsPronounceable )(
|
||||
ISpRecoGrammar * This,
|
||||
/* [string][in] */ const WCHAR *pszWord,
|
||||
/* [out] */ SPWORDPRONOUNCEABLE *pWordPronounceable);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *SetGrammarState )(
|
||||
ISpRecoGrammar * This,
|
||||
/* [in] */ SPGRAMMARSTATE eGrammarState);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *SaveCmd )(
|
||||
ISpRecoGrammar * This,
|
||||
/* [in] */ IStream *pStream,
|
||||
/* [optional][out] */ WCHAR **ppszCoMemErrorText);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetGrammarState )(
|
||||
ISpRecoGrammar * This,
|
||||
/* [out] */ SPGRAMMARSTATE *peGrammarState);
|
||||
} ISpRecoGrammarVtbl;
|
||||
struct ISpRecoGrammar
|
||||
{
|
||||
struct ISpRecoGrammarVtbl *lpVtbl;
|
||||
};
|
||||
|
||||
static ISpRecoContext *stt_recctx = NULL;
|
||||
static ISpRecoGrammar *stt_gram = NULL;
|
||||
void STT_Event(void)
|
||||
{
|
||||
WCHAR *wstring, *i;
|
||||
struct SPEVENT ev;
|
||||
ISpRecoResult *rr;
|
||||
HRESULT hr;
|
||||
char asc[2048], *o;
|
||||
int l;
|
||||
unsigned short c;
|
||||
char *nib = "0123456789abcdef";
|
||||
if (!stt_gram)
|
||||
return;
|
||||
|
||||
while (SUCCEEDED(hr = stt_recctx->lpVtbl->GetEvents(stt_recctx, 1, &ev, NULL)) && hr != S_FALSE)
|
||||
{
|
||||
rr = (ISpRecoResult*)ev.lParam;
|
||||
rr->lpVtbl->GetText(rr, -1, -1, TRUE, &wstring, NULL);
|
||||
for (l = sizeof(asc)-1, o = asc, i = wstring; l > 0 && *i; )
|
||||
{
|
||||
c = *i++;
|
||||
if (c == '\n' || c == ';')
|
||||
{
|
||||
}
|
||||
else if (c < 128)
|
||||
{
|
||||
*o++ = c;
|
||||
l--;
|
||||
}
|
||||
else if (l > 6)
|
||||
{
|
||||
*o++ = '^';
|
||||
*o++ = 'U';
|
||||
*o++ = nib[(c>>12)&0xf];
|
||||
*o++ = nib[(c>>8)&0xf];
|
||||
*o++ = nib[(c>>4)&0xf];
|
||||
*o++ = nib[(c>>0)&0xf];
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
*o = 0;
|
||||
CoTaskMemFree(wstring);
|
||||
Cbuf_AddText("say tts ", RESTRICT_LOCAL);
|
||||
Cbuf_AddText(asc, RESTRICT_LOCAL);
|
||||
Cbuf_AddText("\n", RESTRICT_LOCAL);
|
||||
rr->lpVtbl->Release(rr);
|
||||
}
|
||||
}
|
||||
void STT_Init_f(void)
|
||||
{
|
||||
static CLSID CLSID_SpSharedRecoContext = {0x47206204, 0x5ECA, 0x11D2, 0x96, 0x0F, 0x00, 0xC0, 0x4F, 0x8E, 0xE6, 0x28};
|
||||
static CLSID IID_SpRecoContext = {0xF740A62F, 0x7C15, 0x489E, 0x82, 0x34, 0x94, 0x0A, 0x33, 0xD9, 0x27, 0x2D};
|
||||
|
||||
if (stt_gram)
|
||||
{
|
||||
stt_gram->lpVtbl->Release(stt_gram);
|
||||
stt_recctx->lpVtbl->Release(stt_recctx);
|
||||
stt_gram = NULL;
|
||||
stt_recctx = NULL;
|
||||
Con_Printf("Speech-to-text disabled\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (SUCCEEDED(CoCreateInstance(&CLSID_SpSharedRecoContext, NULL, CLSCTX_SERVER, &IID_SpRecoContext, &stt_recctx)))
|
||||
{
|
||||
ULONGLONG ev = (((ULONGLONG)1) << 38) | (((ULONGLONG)1) << 30) | (((ULONGLONG)1) << 33);
|
||||
if (SUCCEEDED(stt_recctx->lpVtbl->SetNotifyWindowMessage(stt_recctx, mainwindow, WM_USER, 0, 0)))
|
||||
if (SUCCEEDED(stt_recctx->lpVtbl->SetInterest(stt_recctx, ev, ev)))
|
||||
if (SUCCEEDED(stt_recctx->lpVtbl->CreateGrammar(stt_recctx, 0, &stt_gram)))
|
||||
{
|
||||
if (SUCCEEDED(stt_gram->lpVtbl->LoadDictation(stt_gram, NULL, 0)))
|
||||
if (SUCCEEDED(stt_gram->lpVtbl->SetDictationState(stt_gram, 1)))
|
||||
{
|
||||
//success!
|
||||
Con_Printf("Speech-to-text active\n");
|
||||
return;
|
||||
}
|
||||
stt_gram->lpVtbl->Release(stt_gram);
|
||||
}
|
||||
stt_recctx->lpVtbl->Release(stt_recctx);
|
||||
}
|
||||
stt_gram = NULL;
|
||||
stt_recctx = NULL;
|
||||
|
||||
Con_Printf("Speech-to-text unavailable\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
qboolean S_LoadMP3Sound (sfx_t *s, qbyte *data, int datalen, int sndspeed);
|
||||
|
@ -3127,6 +3543,7 @@ void Media_Init(void)
|
|||
{
|
||||
#ifdef _WIN32
|
||||
Cmd_AddCommand("tts", TTS_Say_f);
|
||||
Cmd_AddCommand("stt", STT_Init_f);
|
||||
Cvar_Register(&tts_mode, "Gimmicks");
|
||||
#endif
|
||||
|
||||
|
|
|
@ -212,16 +212,17 @@ typedef enum uploadfmt
|
|||
//not all modes accept meshes - STENCIL(intentional) and DEPTHONLY(not implemented)
|
||||
typedef enum backendmode_e
|
||||
{
|
||||
BEM_STANDARD, //regular mode to draw surfaces akin to q3 (aka: legacy mode). lightmaps+delux+ambient
|
||||
BEM_DEPTHONLY, //just a quick depth pass. textures used only for alpha test (shadowmaps).
|
||||
BEM_STENCIL, //used for drawing shadow volumes to the stencil buffer.
|
||||
BEM_DEPTHDARK, //a quick depth pass. textures used only for alpha test. additive textures still shown as normal.
|
||||
BEM_STANDARD, //regular mode to draw surfaces akin to q3 (aka: legacy mode). lightmaps+delux+ambient
|
||||
BEM_DEPTHONLY, //just a quick depth pass. textures used only for alpha test (shadowmaps).
|
||||
BEM_WIREFRAME, //for debugging or something
|
||||
BEM_STENCIL, //used for drawing shadow volumes to the stencil buffer.
|
||||
BEM_DEPTHDARK, //a quick depth pass. textures used only for alpha test. additive textures still shown as normal.
|
||||
BEM_CREPUSCULAR, //sky is special, everything else completely black
|
||||
BEM_DEPTHNORM, //all opaque stuff drawn using 'depthnorm' shader
|
||||
BEM_LIGHT, //we have a valid light
|
||||
BEM_SMAPLIGHTSPOT, //we have a spot light using a shadowmap
|
||||
BEM_SMAPLIGHT, //we have a light using a shadowmap
|
||||
BEM_FOG //drawing a fog volume
|
||||
BEM_LIGHT, //we have a valid light
|
||||
BEM_SMAPLIGHTSPOT, //we have a spot light using a shadowmap
|
||||
BEM_SMAPLIGHT, //we have a light using a shadowmap
|
||||
BEM_FOG //drawing a fog volume
|
||||
} backendmode_t;
|
||||
|
||||
typedef struct rendererinfo_s {
|
||||
|
|
|
@ -73,6 +73,8 @@ cvar_t r_bouncysparks = CVARFD ("r_bouncysparks", "0",
|
|||
cvar_t r_drawentities = CVAR ("r_drawentities", "1");
|
||||
cvar_t r_drawflat = CVARF ("r_drawflat", "0",
|
||||
CVAR_ARCHIVE | CVAR_SEMICHEAT | CVAR_RENDERERCALLBACK | CVAR_SHADERSYSTEM);
|
||||
cvar_t r_wireframe = CVARF ("r_wireframe", "0",
|
||||
CVAR_CHEAT);
|
||||
cvar_t gl_miptexLevel = CVAR ("gl_miptexLevel", "0");
|
||||
cvar_t r_drawviewmodel = CVARF ("r_drawviewmodel", "1", CVAR_ARCHIVE);
|
||||
cvar_t r_drawviewmodelinvis = CVAR ("r_drawviewmodelinvis", "0");
|
||||
|
@ -595,6 +597,7 @@ void Renderer_Init(void)
|
|||
Cvar_Register (&r_sun_dir, GRAPHICALNICETIES);
|
||||
Cvar_Register (&r_sun_colour, GRAPHICALNICETIES);
|
||||
Cvar_Register (&r_waterstyle, GRAPHICALNICETIES);
|
||||
Cvar_Register (&r_wireframe, GRAPHICALNICETIES);
|
||||
|
||||
Cvar_Register(&scr_viewsize, SCREENOPTIONS);
|
||||
Cvar_Register(&scr_fov, SCREENOPTIONS);
|
||||
|
|
|
@ -132,9 +132,9 @@ void RQ_Init(void)
|
|||
if (initialque)
|
||||
return;
|
||||
|
||||
initialque = (renderque_t *) Hunk_AllocName (rquesize * sizeof(renderque_t), "renderque");
|
||||
|
||||
|
||||
initialque = (renderque_t *) Z_Malloc (rquesize * sizeof(renderque_t));
|
||||
|
||||
|
||||
freerque = &initialque[0];
|
||||
activerque = NULL;
|
||||
|
||||
|
|
|
@ -638,7 +638,6 @@ void Mod_ParseInfoFromEntityLump(model_t *wmodel, char *data, char *mapname) //a
|
|||
}
|
||||
else if (!strcmp("fog", key))
|
||||
{
|
||||
char *s;
|
||||
void CL_Fog_f(void);
|
||||
key[0] = 'f';
|
||||
key[1] = ' ';
|
||||
|
|
|
@ -398,7 +398,7 @@ typedef struct q2miptex_s
|
|||
#define MAX_Q2MAP_EDGES 128000
|
||||
#define MAX_Q2MAP_SURFEDGES 256000
|
||||
#define MAX_Q2MAP_LIGHTING 0x200000
|
||||
#define MAX_Q2MAP_VISIBILITY MAX_MAP_VISIBILITY
|
||||
//#define MAX_Q2MAP_VISIBILITY MAX_MAP_VISIBILITY
|
||||
|
||||
// key / value pair sizes
|
||||
|
||||
|
|
|
@ -2593,6 +2593,17 @@ void FS_StartupWithGame(int gamenum)
|
|||
COM_Gamedir(com_argv[i+1]);
|
||||
}
|
||||
|
||||
#if 1//def ANDROID
|
||||
{
|
||||
vfsfile_t *f;
|
||||
//write a .nomedia file to avoid people from getting random explosion sounds etc intersperced with their music
|
||||
f = FS_OpenVFS(".nomedia", "rb", FS_ROOT);
|
||||
if (f)
|
||||
VFS_CLOSE(f);
|
||||
else
|
||||
FS_WriteFile(".nomedia", NULL, 0, FS_ROOT);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (gamemode_info[gamenum].customexec)
|
||||
Cbuf_AddText(gamemode_info[gamenum].customexec, RESTRICT_LOCAL);
|
||||
|
|
|
@ -1093,7 +1093,8 @@ void Q1BSP_MarkLights (dlight_t *light, int bit, mnode_t *node)
|
|||
#define MAXFRAGMENTTRIS 256
|
||||
vec3_t decalfragmentverts[MAXFRAGMENTTRIS*3];
|
||||
|
||||
typedef struct {
|
||||
struct fragmentdecal_s
|
||||
{
|
||||
vec3_t center;
|
||||
|
||||
vec3_t normal;
|
||||
|
@ -1106,8 +1107,8 @@ typedef struct {
|
|||
|
||||
vec_t radius;
|
||||
int numtris;
|
||||
|
||||
} fragmentdecal_t;
|
||||
};
|
||||
typedef struct fragmentdecal_s fragmentdecal_t;
|
||||
|
||||
//#define SHOWCLIPS
|
||||
//#define FRAGMENTASTRIANGLES //works, but produces more fragments.
|
||||
|
@ -1115,7 +1116,7 @@ typedef struct {
|
|||
#ifdef FRAGMENTASTRIANGLES
|
||||
|
||||
//if the triangle is clipped away, go recursive if there are tris left.
|
||||
void Fragment_ClipTriToPlane(int trinum, float *plane, float planedist, fragmentdecal_t *dec)
|
||||
static void Fragment_ClipTriToPlane(int trinum, float *plane, float planedist, fragmentdecal_t *dec)
|
||||
{
|
||||
float *point[3];
|
||||
float dotv[3];
|
||||
|
@ -1249,7 +1250,7 @@ void Fragment_ClipTriToPlane(int trinum, float *plane, float planedist, fragment
|
|||
}
|
||||
}
|
||||
|
||||
void Fragment_ClipTriangle(fragmentdecal_t *dec, float *a, float *b, float *c)
|
||||
static void Fragment_ClipTriangle(fragmentdecal_t *dec, float *a, float *b, float *c)
|
||||
{
|
||||
//emit the triangle, and clip it's fragments.
|
||||
int start, i;
|
||||
|
@ -1279,7 +1280,7 @@ void Fragment_ClipTriangle(fragmentdecal_t *dec, float *a, float *b, float *c)
|
|||
#else
|
||||
|
||||
#define MAXFRAGMENTVERTS 360
|
||||
int Fragment_ClipPolyToPlane(float *inverts, float *outverts, int incount, float *plane, float planedist)
|
||||
static int Fragment_ClipPolyToPlane(float *inverts, float *outverts, int incount, float *plane, float planedist)
|
||||
{
|
||||
#define C 4
|
||||
float dotv[MAXFRAGMENTVERTS+1];
|
||||
|
@ -1400,7 +1401,7 @@ void Fragment_ClipPoly(fragmentdecal_t *dec, int numverts, float *inverts)
|
|||
#endif
|
||||
|
||||
//this could be inlined, but I'm lazy.
|
||||
void Fragment_Mesh (fragmentdecal_t *dec, mesh_t *mesh)
|
||||
static void Fragment_Mesh (fragmentdecal_t *dec, mesh_t *mesh)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -1428,7 +1429,7 @@ void Fragment_Mesh (fragmentdecal_t *dec, mesh_t *mesh)
|
|||
}
|
||||
}
|
||||
|
||||
void Q1BSP_ClipDecalToNodes (fragmentdecal_t *dec, mnode_t *node)
|
||||
static void Q1BSP_ClipDecalToNodes (fragmentdecal_t *dec, mnode_t *node)
|
||||
{
|
||||
mplane_t *splitplane;
|
||||
float dist;
|
||||
|
@ -1479,7 +1480,7 @@ extern int sh_shadowframe;
|
|||
static int sh_shadowframe;
|
||||
#endif
|
||||
#ifdef Q3BSPS
|
||||
void Q3BSP_ClipDecalToNodes (fragmentdecal_t *dec, mnode_t *node)
|
||||
static void Q3BSP_ClipDecalToNodes (fragmentdecal_t *dec, mnode_t *node)
|
||||
{
|
||||
mplane_t *splitplane;
|
||||
float dist;
|
||||
|
@ -1547,8 +1548,9 @@ int Q1BSP_ClipDecal(vec3_t center, vec3_t normal, vec3_t tangent1, vec3_t tangen
|
|||
|
||||
sh_shadowframe++;
|
||||
|
||||
if (!cl.worldmodel)
|
||||
return 0;
|
||||
if (!cl.worldmodel || cl.worldmodel->type != mod_brush)
|
||||
{
|
||||
}
|
||||
else if (cl.worldmodel->fromgame == fg_quake)
|
||||
Q1BSP_ClipDecalToNodes(&dec, cl.worldmodel->nodes);
|
||||
#ifdef Q3BSPS
|
||||
|
@ -1556,96 +1558,15 @@ int Q1BSP_ClipDecal(vec3_t center, vec3_t normal, vec3_t tangent1, vec3_t tangen
|
|||
Q3BSP_ClipDecalToNodes(&dec, cl.worldmodel->nodes);
|
||||
#endif
|
||||
|
||||
#ifdef TERRAIN
|
||||
if (cl.worldmodel->terrain)
|
||||
Terrain_ClipDecal(&dec, center, dec.radius, cl.worldmodel);
|
||||
#endif
|
||||
|
||||
*out = (float *)decalfragmentverts;
|
||||
return dec.numtris;
|
||||
}
|
||||
|
||||
//This is spike's testing function, and is only usable by gl. :)
|
||||
/*
|
||||
#include "glquake.h"
|
||||
void Q1BSP_TestClipDecal(void)
|
||||
{
|
||||
int i;
|
||||
int numtris;
|
||||
vec3_t fwd;
|
||||
vec3_t start;
|
||||
vec3_t center, normal, tangent, tangent2;
|
||||
float *verts;
|
||||
|
||||
if (cls.state != ca_active)
|
||||
return;
|
||||
|
||||
VectorCopy(r_origin, start);
|
||||
// start[2]+=22;
|
||||
VectorMA(start, 10000, vpn, fwd);
|
||||
|
||||
if (!TraceLineN(start, fwd, center, normal))
|
||||
{
|
||||
VectorCopy(start, center);
|
||||
normal[0] = 0;
|
||||
normal[1] = 0;
|
||||
normal[2] = 1;
|
||||
}
|
||||
|
||||
CrossProduct(fwd, normal, tangent);
|
||||
VectorNormalize(tangent);
|
||||
|
||||
CrossProduct(normal, tangent, tangent2);
|
||||
|
||||
numtris = Q1BSP_ClipDecal(center, normal, tangent, tangent2, 128, &verts);
|
||||
PPL_RevertToKnownState();
|
||||
qglDisable(GL_TEXTURE_2D);
|
||||
qglDisable(GL_BLEND);
|
||||
qglDisable(GL_ALPHA_TEST);
|
||||
qglDisable(GL_DEPTH_TEST);
|
||||
|
||||
qglColor3f(1, 0, 0);
|
||||
qglShadeModel(GL_SMOOTH);
|
||||
qglBegin(GL_TRIANGLES);
|
||||
for (i = 0; i < numtris; i++)
|
||||
{
|
||||
qglVertex3fv(verts+i*9+0);
|
||||
qglVertex3fv(verts+i*9+3);
|
||||
qglVertex3fv(verts+i*9+6);
|
||||
}
|
||||
qglEnd();
|
||||
|
||||
qglColor3f(1, 1, 1);
|
||||
qglBegin(GL_LINES);
|
||||
for (i = 0; i < numtris; i++)
|
||||
{
|
||||
qglVertex3fv(verts+i*9+0);
|
||||
qglVertex3fv(verts+i*9+3);
|
||||
qglVertex3fv(verts+i*9+3);
|
||||
qglVertex3fv(verts+i*9+6);
|
||||
qglVertex3fv(verts+i*9+6);
|
||||
qglVertex3fv(verts+i*9+0);
|
||||
}
|
||||
|
||||
qglVertex3fv(center);
|
||||
VectorMA(center, 10, normal, fwd);
|
||||
qglVertex3fv(fwd);
|
||||
|
||||
qglColor3f(0, 1, 0);
|
||||
qglVertex3fv(center);
|
||||
VectorMA(center, 10, tangent, fwd);
|
||||
qglVertex3fv(fwd);
|
||||
|
||||
qglColor3f(0, 0, 1);
|
||||
qglVertex3fv(center);
|
||||
CrossProduct(tangent, normal, fwd);
|
||||
VectorMA(center, 10, fwd, fwd);
|
||||
qglVertex3fv(fwd);
|
||||
|
||||
qglColor3f(1, 1, 1);
|
||||
|
||||
qglEnd();
|
||||
qglEnable(GL_TEXTURE_2D);
|
||||
qglEnable(GL_DEPTH_TEST);
|
||||
PPL_RevertToKnownState();
|
||||
}
|
||||
*/
|
||||
|
||||
#endif
|
||||
/*
|
||||
Rendering functions (Client only)
|
||||
|
|
|
@ -1230,7 +1230,7 @@ void Hunk_Check (void)
|
|||
for (h = (hunk_t *)hunk_base ; (qbyte *)h != hunk_base + hunk_low_used ; )
|
||||
{
|
||||
if (h->sentinal != HUNK_SENTINAL)
|
||||
Sys_Error ("Hunk_Check: trahsed sentinal");
|
||||
Sys_Error ("Hunk_Check: trashed sentinal");
|
||||
if (h->size < 16+HUNKDEBUG*2 || h->size + (qbyte *)h - hunk_base > hunk_size)
|
||||
Sys_Error ("Hunk_Check: bad size");
|
||||
#if HUNKDEBUG > 0
|
||||
|
@ -1243,9 +1243,9 @@ void Hunk_Check (void)
|
|||
for (i = 0; i < HUNKDEBUG; i++)
|
||||
{
|
||||
if (present[i] != sentinalkey)
|
||||
*(int*)0 = -3;
|
||||
Sys_Error ("Hunk_Check: trashed pre-sentinal on \"%s\"", h->name);
|
||||
if (postsent[i] != sentinalkey)
|
||||
*(int*)0 = -3;
|
||||
Sys_Error ("Hunk_Check: trashed post-sentinal on \"%s\"", h->name);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#include "quakedef.h"
|
||||
|
||||
//#define FORCESTATE
|
||||
//#define WIREFRAME
|
||||
|
||||
#ifdef GLQUAKE
|
||||
|
||||
|
@ -26,7 +25,9 @@
|
|||
|
||||
extern cvar_t gl_overbright;
|
||||
extern cvar_t gl_ati_truform;
|
||||
extern cvar_t r_wireframe;
|
||||
|
||||
//simple dlight
|
||||
static const char LIGHTPASS_SHADER[] = "\
|
||||
{\n\
|
||||
program rtlight%s\n\
|
||||
|
@ -41,7 +42,8 @@ static const char LIGHTPASS_SHADER[] = "\
|
|||
map $specular\n\
|
||||
}\n\
|
||||
}";
|
||||
static const char RTLIGHTCUBE_SHADER[] = "\
|
||||
//dlight with cubemap projection
|
||||
static const char RTLIGHTCUBEPROJ_SHADER[] = "\
|
||||
{\n\
|
||||
program rtlight%s\n\
|
||||
{\n\
|
||||
|
@ -79,6 +81,9 @@ static const char PCFPASS_SHADER[] = "\
|
|||
{\n\
|
||||
map $specular\n\
|
||||
}\n\
|
||||
{\n\
|
||||
map $lightcubemap\n\
|
||||
}\n\
|
||||
{\n\
|
||||
map $shadowmap\n\
|
||||
}\n\
|
||||
|
@ -102,8 +107,8 @@ struct {
|
|||
|
||||
qboolean inited_shader_rtlight;
|
||||
const shader_t *shader_rtlight;
|
||||
qboolean inited_shader_cube;
|
||||
const shader_t *shader_cube;
|
||||
qboolean inited_shader_cubeproj;
|
||||
const shader_t *shader_cubeproj;
|
||||
qboolean inited_shader_smap;
|
||||
const shader_t *shader_smap;
|
||||
qboolean inited_shader_spot;
|
||||
|
@ -213,44 +218,36 @@ struct {
|
|||
|
||||
static void BE_PolyOffset(qboolean pushdepth)
|
||||
{
|
||||
polyoffset_t po;
|
||||
po.factor = shaderstate.curshader->polyoffset.factor;
|
||||
po.unit = shaderstate.curshader->polyoffset.unit;
|
||||
|
||||
if (pushdepth)
|
||||
{
|
||||
/*some quake doors etc are flush with the walls that they're meant to be hidden behind, or plats the same height as the floor, etc
|
||||
we move them back very slightly using polygonoffset to avoid really ugly z-fighting*/
|
||||
extern cvar_t r_polygonoffset_submodel_offset, r_polygonoffset_submodel_factor;
|
||||
polyoffset_t po;
|
||||
po.factor = shaderstate.curshader->polyoffset.factor + r_polygonoffset_submodel_factor.value;
|
||||
po.unit = shaderstate.curshader->polyoffset.unit + r_polygonoffset_submodel_offset.value;
|
||||
po.factor += r_polygonoffset_submodel_factor.value;
|
||||
po.unit += r_polygonoffset_submodel_offset.value;
|
||||
}
|
||||
if (shaderstate.mode == BEM_DEPTHONLY)
|
||||
{
|
||||
po.factor += 5;
|
||||
po.unit += 25;
|
||||
}
|
||||
|
||||
#ifndef FORCESTATE
|
||||
if (((int*)&shaderstate.curpolyoffset)[0] != ((int*)&po)[0] || ((int*)&shaderstate.curpolyoffset)[1] != ((int*)&po)[1])
|
||||
if (((int*)&shaderstate.curpolyoffset)[0] != ((int*)&po)[0] || ((int*)&shaderstate.curpolyoffset)[1] != ((int*)&po)[1])
|
||||
#endif
|
||||
{
|
||||
shaderstate.curpolyoffset = po;
|
||||
if (shaderstate.curpolyoffset.factor || shaderstate.curpolyoffset.unit)
|
||||
{
|
||||
qglEnable(GL_POLYGON_OFFSET_FILL);
|
||||
qglPolygonOffset(shaderstate.curpolyoffset.factor, shaderstate.curpolyoffset.unit);
|
||||
}
|
||||
else
|
||||
qglDisable(GL_POLYGON_OFFSET_FILL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifndef FORCESTATE
|
||||
if (*(int*)&shaderstate.curpolyoffset.factor != *(int*)&shaderstate.curshader->polyoffset.factor || *(int*)&shaderstate.curpolyoffset.unit != *(int*)&shaderstate.curshader->polyoffset.unit)
|
||||
#endif
|
||||
shaderstate.curpolyoffset = po;
|
||||
if (shaderstate.curpolyoffset.factor || shaderstate.curpolyoffset.unit)
|
||||
{
|
||||
shaderstate.curpolyoffset = shaderstate.curshader->polyoffset;
|
||||
if (shaderstate.curpolyoffset.factor || shaderstate.curpolyoffset.unit)
|
||||
{
|
||||
qglEnable(GL_POLYGON_OFFSET_FILL);
|
||||
qglPolygonOffset(shaderstate.curpolyoffset.factor, shaderstate.curpolyoffset.unit);
|
||||
}
|
||||
else
|
||||
qglDisable(GL_POLYGON_OFFSET_FILL);
|
||||
qglEnable(GL_POLYGON_OFFSET_FILL);
|
||||
qglPolygonOffset(shaderstate.curpolyoffset.factor, shaderstate.curpolyoffset.unit);
|
||||
}
|
||||
else
|
||||
qglDisable(GL_POLYGON_OFFSET_FILL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -343,12 +340,6 @@ void GL_SetShaderState2D(qboolean is2d)
|
|||
{
|
||||
shaderstate.updatetime = realtime;
|
||||
shaderstate.force2d = is2d;
|
||||
#ifdef WIREFRAME
|
||||
if (!is2d)
|
||||
qglPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
else
|
||||
qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
#endif
|
||||
if (is2d)
|
||||
memcpy(shaderstate.modelviewmatrix, r_refdef.m_view, sizeof(shaderstate.modelviewmatrix));
|
||||
BE_SelectMode(BEM_STANDARD);
|
||||
|
@ -910,17 +901,19 @@ void R_IBrokeTheArrays(void)
|
|||
|
||||
#ifdef RTLIGHTS
|
||||
//called from gl_shadow
|
||||
void BE_SetupForShadowMap(void)
|
||||
void BE_SetupForShadowMap(texid_t shadowmaptex)
|
||||
{
|
||||
shaderstate.curshadowmap = shadowmaptex;
|
||||
while(shaderstate.lastpasstmus>0)
|
||||
{
|
||||
GL_LazyBind(--shaderstate.lastpasstmus, 0, r_nulltex);
|
||||
}
|
||||
|
||||
shaderstate.shaderbits &= ~SBITS_MISC_DEPTHWRITE;
|
||||
|
||||
qglShadeModel(GL_FLAT);
|
||||
BE_SetPassBlendMode(0, PBM_REPLACE);
|
||||
qglDepthMask(GL_TRUE);
|
||||
shaderstate.shaderbits |= SBITS_MISC_DEPTHWRITE;
|
||||
GL_ForceDepthWritable();
|
||||
// qglColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||
|
||||
BE_SelectMode(BEM_DEPTHONLY);
|
||||
|
@ -930,6 +923,9 @@ void BE_SetupForShadowMap(void)
|
|||
static void T_Gen_CurrentRender(int tmu)
|
||||
{
|
||||
int vwidth, vheight;
|
||||
if (r_refdef.recurse)
|
||||
return;
|
||||
|
||||
if (gl_config.arb_texture_non_power_of_two)
|
||||
{
|
||||
vwidth = vid.pixelwidth;
|
||||
|
@ -1140,10 +1136,10 @@ void Shader_LightPass_Std(char *shortname, shader_t *s, const void *args)
|
|||
sprintf(shadertext, LIGHTPASS_SHADER, "");
|
||||
Shader_DefaultScript(shortname, s, shadertext);
|
||||
}
|
||||
void Shader_LightPass_Cube(char *shortname, shader_t *s, const void *args)
|
||||
void Shader_LightPass_CubeProj(char *shortname, shader_t *s, const void *args)
|
||||
{
|
||||
char shadertext[8192*2];
|
||||
sprintf(shadertext, RTLIGHTCUBE_SHADER, "#CUBE");
|
||||
sprintf(shadertext, RTLIGHTCUBEPROJ_SHADER, "#CUBEPROJ");
|
||||
Shader_DefaultScript(shortname, s, shadertext);
|
||||
}
|
||||
void Shader_LightPass_PCF(char *shortname, shader_t *s, const void *args)
|
||||
|
@ -1246,10 +1242,10 @@ void GLBE_Init(void)
|
|||
shaderstate.inited_shader_rtlight = true;
|
||||
shaderstate.shader_rtlight = R_RegisterCustom("rtlight", Shader_LightPass_Std, NULL);
|
||||
}
|
||||
if (r_shadow_realtime_dlight.ival && !shaderstate.inited_shader_cube && gl_config.arb_shader_objects)
|
||||
if (r_shadow_realtime_dlight.ival && !shaderstate.inited_shader_cubeproj && gl_config.arb_shader_objects)
|
||||
{
|
||||
shaderstate.inited_shader_cube = true;
|
||||
shaderstate.shader_cube = R_RegisterCustom("rtlight_sube", Shader_LightPass_Cube, NULL);
|
||||
shaderstate.inited_shader_cubeproj = true;
|
||||
shaderstate.shader_cubeproj = R_RegisterCustom("rtlight_cubeproj", Shader_LightPass_CubeProj, NULL);
|
||||
}
|
||||
|
||||
gl_overbright.modified = true; /*in case the d3d renderer does the same*/
|
||||
|
@ -2842,10 +2838,17 @@ static void BE_Program_Set_Attributes(const program_t *prog, unsigned int perm,
|
|||
qglUniform3fvARB(p->handle[perm], 1, shaderstate.lightcolourscale);
|
||||
break;
|
||||
case SP_LIGHTPROJMATRIX:
|
||||
{
|
||||
float t[16];
|
||||
Matrix4x4_CM_Projection_Far(t, 90, 90, 4, 3000);
|
||||
qglUniformMatrix4fvARB(p->handle[perm], 1, false, t);
|
||||
}
|
||||
break;
|
||||
case SP_LIGHTCUBEMATRIX:
|
||||
/*light's texture projection matrix*/
|
||||
{
|
||||
float t[16];
|
||||
Matrix4_Multiply(shaderstate.lightprojmatrix, shaderstate.modelmatrix, t);
|
||||
Matrix4_Multiply(shaderstate.modelmatrix, shaderstate.lightprojmatrix, t);
|
||||
qglUniformMatrix4fvARB(p->handle[perm], 1, false, t);
|
||||
}
|
||||
break;
|
||||
|
@ -3105,10 +3108,10 @@ void GLBE_SelectMode(backendmode_t mode)
|
|||
shaderstate.inited_shader_rtlight = true;
|
||||
shaderstate.shader_rtlight = R_RegisterCustom("rtlight", Shader_LightPass_Std, NULL);
|
||||
}
|
||||
if (!shaderstate.inited_shader_cube && gl_config.arb_shader_objects)
|
||||
if (!shaderstate.inited_shader_cubeproj && gl_config.arb_shader_objects)
|
||||
{
|
||||
shaderstate.inited_shader_cube = true;
|
||||
shaderstate.shader_cube = R_RegisterCustom("rtlight_sube", Shader_LightPass_Cube, NULL);
|
||||
shaderstate.inited_shader_cubeproj = true;
|
||||
shaderstate.shader_cubeproj = R_RegisterCustom("rtlight_sube", Shader_LightPass_CubeProj, NULL);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -3197,34 +3200,27 @@ void BE_SelectFog(vec3_t colour, float alpha, float density)
|
|||
|
||||
void GLBE_SelectDLight(dlight_t *dl, vec3_t colour)
|
||||
{
|
||||
static float shadowprojectionbias[16] =
|
||||
{
|
||||
0.5f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.5f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.5f, 0.0f,
|
||||
0.5f, 0.5f, 0.4993f, 1.0f
|
||||
};
|
||||
float view[16], proj[16], t[16];
|
||||
float view[16], proj[16];
|
||||
|
||||
/*generate light projection information*/
|
||||
float nearplane = 4;
|
||||
if (dl->fov)
|
||||
{
|
||||
Matrix4x4_CM_Projection_Far(proj, dl->fov, dl->fov, nearplane, dl->radius);
|
||||
Matrix4x4_CM_ModelViewMatrixFromAxis(view, dl->axis[0], dl->axis[1], dl->axis[2], dl->origin);
|
||||
Matrix4_Multiply(proj, view, shaderstate.lightprojmatrix);
|
||||
}
|
||||
else
|
||||
{
|
||||
Matrix4x4_CM_Projection_Far(proj, 90, 90, nearplane, dl->radius);
|
||||
Matrix4x4_CM_ModelViewMatrixFromAxis(view, dl->axis[0], dl->axis[1], dl->axis[2], dl->origin);
|
||||
Matrix4_Multiply(shadowprojectionbias, proj, t);
|
||||
Matrix4_Multiply(proj, view, shaderstate.lightprojmatrix);
|
||||
|
||||
Matrix4x4_CM_ModelViewMatrixFromAxis(shaderstate.lightprojmatrix, dl->axis[0], dl->axis[1], dl->axis[2], dl->origin);
|
||||
}
|
||||
|
||||
/*simple info*/
|
||||
shaderstate.lightradius = dl->radius;
|
||||
VectorCopy(dl->origin, shaderstate.lightorg);
|
||||
VectorCopy(dl->lightcolourscales, shaderstate.lightcolourscale);
|
||||
VectorCopy(colour, shaderstate.lightcolours);
|
||||
#ifdef RTLIGHTS
|
||||
shaderstate.curshadowmap = dl->stexture;
|
||||
#endif
|
||||
#ifdef RTLIGHTS
|
||||
shaderstate.lightcubemap = dl->cubetexture;
|
||||
#endif
|
||||
|
@ -3436,10 +3432,12 @@ static void DrawMeshes(void)
|
|||
break;
|
||||
#ifdef RTLIGHTS
|
||||
case BEM_SMAPLIGHTSPOT:
|
||||
BE_RenderMeshProgram(shaderstate.shader_spot, shaderstate.shader_spot->passes);
|
||||
if (shaderstate.shader_smap->prog)
|
||||
BE_RenderMeshProgram(shaderstate.shader_spot, shaderstate.shader_spot->passes);
|
||||
break;
|
||||
case BEM_SMAPLIGHT:
|
||||
BE_RenderMeshProgram(shaderstate.shader_smap, shaderstate.shader_smap->passes);
|
||||
if (shaderstate.shader_smap->prog)
|
||||
BE_RenderMeshProgram(shaderstate.shader_smap, shaderstate.shader_smap->passes);
|
||||
break;
|
||||
case BEM_LIGHT:
|
||||
if (!shaderstate.inited_shader_rtlight)
|
||||
|
@ -3447,9 +3445,9 @@ static void DrawMeshes(void)
|
|||
BE_LegacyLighting();
|
||||
break;
|
||||
}
|
||||
if (TEXVALID(shaderstate.lightcubemap))
|
||||
BE_RenderMeshProgram(shaderstate.shader_cube, shaderstate.shader_cube->passes);
|
||||
else
|
||||
if (TEXVALID(shaderstate.lightcubemap) && shaderstate.shader_cubeproj->prog)
|
||||
BE_RenderMeshProgram(shaderstate.shader_cubeproj, shaderstate.shader_cubeproj->passes);
|
||||
else if (shaderstate.shader_rtlight->prog)
|
||||
BE_RenderMeshProgram(shaderstate.shader_rtlight, shaderstate.shader_rtlight->passes);
|
||||
break;
|
||||
case BEM_DEPTHNORM:
|
||||
|
@ -3481,6 +3479,23 @@ static void DrawMeshes(void)
|
|||
BE_SubmitMeshChain();
|
||||
break;
|
||||
|
||||
case BEM_WIREFRAME:
|
||||
//FIXME: do this with a shader instead? its not urgent as we can draw the shader normally anyway, just faster.
|
||||
GL_DeselectVAO();
|
||||
GL_DeSelectProgram();
|
||||
shaderstate.pendingcolourvbo = 0;
|
||||
shaderstate.pendingcolourpointer = NULL;
|
||||
Vector4Set(shaderstate.pendingcolourflat, 1, 1, 1, 1);
|
||||
while(shaderstate.lastpasstmus>0)
|
||||
{
|
||||
GL_LazyBind(--shaderstate.lastpasstmus, 0, r_nulltex);
|
||||
}
|
||||
BE_SetPassBlendMode(0, PBM_REPLACE);
|
||||
BE_SendPassBlendDepthMask(shaderstate.curshader->passes[0].shaderbits | SBITS_MISC_NODEPTHTEST);
|
||||
|
||||
BE_EnableShaderAttributes((1u<<VATTR_LEG_VERTEX) | (1u<<VATTR_LEG_COLOUR));
|
||||
BE_SubmitMeshChain();
|
||||
break;
|
||||
case BEM_DEPTHDARK:
|
||||
if ((shaderstate.curshader->flags & SHADER_HASLIGHTMAP) && !TEXVALID(shaderstate.curtexnums->fullbright) && !gl_config.nofixedfunc)
|
||||
{
|
||||
|
@ -3756,15 +3771,17 @@ static void GLBE_SubmitMeshesSortList(batch_t *sortlist)
|
|||
continue;
|
||||
}
|
||||
}
|
||||
else if (shaderstate.mode != BEM_FOG && shaderstate.mode != BEM_CREPUSCULAR)
|
||||
else if (shaderstate.mode != BEM_FOG && shaderstate.mode != BEM_CREPUSCULAR && shaderstate.mode != BEM_WIREFRAME)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (batch->shader->flags & (SHADER_HASREFLECT | SHADER_HASREFRACT | SHADER_HASRIPPLEMAP))
|
||||
if ((batch->shader->flags & (SHADER_HASREFLECT | SHADER_HASREFRACT | SHADER_HASRIPPLEMAP)) && shaderstate.mode != BEM_WIREFRAME)
|
||||
{
|
||||
//these flags require rendering some view as an fbo
|
||||
if (r_refdef.recurse)
|
||||
continue;
|
||||
if (shaderstate.mode != BEM_STANDARD && shaderstate.mode != BEM_DEPTHDARK)
|
||||
continue;
|
||||
|
||||
if (batch->shader->flags & SHADER_HASREFLECT)
|
||||
{
|
||||
|
@ -4227,7 +4244,7 @@ void GLBE_DrawWorld (qboolean drawworld, qbyte *vis)
|
|||
}
|
||||
|
||||
#ifdef RTLIGHTS
|
||||
if (vis)
|
||||
if (drawworld)
|
||||
{
|
||||
RSpeedRemark();
|
||||
TRACE(("GLBE_DrawWorld: drawing lights\n"));
|
||||
|
@ -4249,10 +4266,28 @@ void GLBE_DrawWorld (qboolean drawworld, qbyte *vis)
|
|||
GLBE_SubmitMeshes(true, batches, SHADER_SORT_PORTAL, SHADER_SORT_NEAREST);
|
||||
}
|
||||
*/
|
||||
|
||||
if (r_wireframe.ival)
|
||||
{
|
||||
BE_SelectMode(BEM_WIREFRAME);
|
||||
qglPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
GLBE_SubmitMeshes(true, SHADER_SORT_PORTAL, SHADER_SORT_NEAREST);
|
||||
BE_SelectMode(BEM_STANDARD);
|
||||
qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GLBE_SubmitMeshes(false, SHADER_SORT_PORTAL, SHADER_SORT_NEAREST);
|
||||
|
||||
if (r_wireframe.ival)
|
||||
{
|
||||
BE_SelectMode(BEM_WIREFRAME);
|
||||
qglPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
GLBE_SubmitMeshes(false, SHADER_SORT_PORTAL, SHADER_SORT_NEAREST);
|
||||
BE_SelectMode(BEM_STANDARD);
|
||||
qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
}
|
||||
}
|
||||
|
||||
BE_SelectEntity(&r_worldentity);
|
||||
|
|
|
@ -298,6 +298,7 @@ void GL_Texturemode_Callback (struct cvar_s *var, char *oldvalue)
|
|||
{
|
||||
int i;
|
||||
gltexture_t *glt;
|
||||
int targ;
|
||||
|
||||
if (qrenderer != QR_OPENGL)
|
||||
return;
|
||||
|
@ -323,12 +324,17 @@ void GL_Texturemode_Callback (struct cvar_s *var, char *oldvalue)
|
|||
{
|
||||
if (!(glt->flags & IF_NOMIPMAP))
|
||||
{
|
||||
GL_MTBind(0, GL_TEXTURE_2D, glt->texnum);
|
||||
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
|
||||
if (glt->flags & IF_NEAREST)
|
||||
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
if (glt->flags & IF_CUBEMAP)
|
||||
targ = GL_TEXTURE_CUBE_MAP_ARB;
|
||||
else
|
||||
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
|
||||
targ = GL_TEXTURE_2D;
|
||||
|
||||
GL_MTBind(0, targ, glt->texnum);
|
||||
qglTexParameteri(targ, GL_TEXTURE_MIN_FILTER, gl_filter_min);
|
||||
if (glt->flags & IF_NEAREST)
|
||||
qglTexParameteri(targ, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
else
|
||||
qglTexParameteri(targ, GL_TEXTURE_MAG_FILTER, gl_filter_max);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1127,7 +1133,7 @@ void GL_Upload32_Int (char *name, unsigned *data, int width, int height, unsigne
|
|||
unsigned *scaled = (unsigned *)uploadmemorybuffer;
|
||||
int scaled_width, scaled_height;
|
||||
int type;
|
||||
int targ;
|
||||
int targ, targface;
|
||||
|
||||
TRACE(("dbg: GL_Upload32: %s %i %i\n", name, width, height));
|
||||
|
||||
|
@ -1152,13 +1158,14 @@ void GL_Upload32_Int (char *name, unsigned *data, int width, int height, unsigne
|
|||
switch((flags & IF_TEXTYPE) >> IF_TEXTYPESHIFT)
|
||||
{
|
||||
case 0:
|
||||
targ = GL_TEXTURE_2D;
|
||||
targface = targ = GL_TEXTURE_2D;
|
||||
break;
|
||||
case 1:
|
||||
targ = GL_TEXTURE_3D;
|
||||
targface = targ = GL_TEXTURE_3D;
|
||||
break;
|
||||
default:
|
||||
targ = GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + (((flags & IF_TEXTYPE) >> IF_TEXTYPESHIFT) - 2);
|
||||
targface = GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + (((flags & IF_TEXTYPE) >> IF_TEXTYPESHIFT) - 2);
|
||||
targ = GL_TEXTURE_CUBE_MAP_ARB;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1265,11 +1272,11 @@ void GL_Upload32_Int (char *name, unsigned *data, int width, int height, unsigne
|
|||
{
|
||||
TRACE(("dbg: GL_Upload32: non-mipmapped/unscaled\n"));
|
||||
if (type == GL_UNSIGNED_SHORT_5_6_5)
|
||||
GL_8888to565(targ, (unsigned char *)data, (unsigned short*)scaled, 0, scaled_width, scaled_height);
|
||||
GL_8888to565(targface, (unsigned char *)data, (unsigned short*)scaled, 0, scaled_width, scaled_height);
|
||||
else if (type == GL_UNSIGNED_SHORT_4_4_4_4)
|
||||
GL_8888to4444(targ, (unsigned char *)data, (unsigned short*)scaled, 0, scaled_width, scaled_height);
|
||||
GL_8888to4444(targface, (unsigned char *)data, (unsigned short*)scaled, 0, scaled_width, scaled_height);
|
||||
else
|
||||
qglTexImage2D (targ, 0, samples, scaled_width, scaled_height, 0, glcolormode, GL_UNSIGNED_BYTE, data);
|
||||
qglTexImage2D (targface, 0, samples, scaled_width, scaled_height, 0, glcolormode, GL_UNSIGNED_BYTE, data);
|
||||
goto done;
|
||||
}
|
||||
memcpy (scaled, data, width*height*4);
|
||||
|
@ -1279,11 +1286,11 @@ void GL_Upload32_Int (char *name, unsigned *data, int width, int height, unsigne
|
|||
|
||||
TRACE(("dbg: GL_Upload32: recaled\n"));
|
||||
if (type == GL_UNSIGNED_SHORT_5_6_5)
|
||||
GL_8888to565(targ, (unsigned char *)scaled, (unsigned short*)uploadmemorybufferintermediate, 0, scaled_width, scaled_height);
|
||||
GL_8888to565(targface, (unsigned char *)scaled, (unsigned short*)uploadmemorybufferintermediate, 0, scaled_width, scaled_height);
|
||||
else if (type == GL_UNSIGNED_SHORT_4_4_4_4)
|
||||
GL_8888to4444(targ, (unsigned char *)scaled, (unsigned short*)uploadmemorybufferintermediate, 0, scaled_width, scaled_height);
|
||||
GL_8888to4444(targface, (unsigned char *)scaled, (unsigned short*)uploadmemorybufferintermediate, 0, scaled_width, scaled_height);
|
||||
else
|
||||
qglTexImage2D (targ, 0, samples, scaled_width, scaled_height, 0, glcolormode, GL_UNSIGNED_BYTE, scaled);
|
||||
qglTexImage2D (targface, 0, samples, scaled_width, scaled_height, 0, glcolormode, GL_UNSIGNED_BYTE, scaled);
|
||||
if (!(flags&IF_NOMIPMAP) && !gl_config.sgis_generate_mipmap)
|
||||
{
|
||||
miplevel = 0;
|
||||
|
@ -1299,11 +1306,11 @@ void GL_Upload32_Int (char *name, unsigned *data, int width, int height, unsigne
|
|||
scaled_height = 1;
|
||||
miplevel++;
|
||||
if (type == GL_UNSIGNED_SHORT_5_6_5)
|
||||
GL_8888to565(targ, (unsigned char *)scaled, (unsigned short*)uploadmemorybufferintermediate, miplevel, scaled_width, scaled_height);
|
||||
GL_8888to565(targface, (unsigned char *)scaled, (unsigned short*)uploadmemorybufferintermediate, miplevel, scaled_width, scaled_height);
|
||||
else if (type == GL_UNSIGNED_SHORT_4_4_4_4)
|
||||
GL_8888to4444(targ, (unsigned char *)scaled, (unsigned short*)uploadmemorybufferintermediate, miplevel, scaled_width, scaled_height);
|
||||
GL_8888to4444(targface, (unsigned char *)scaled, (unsigned short*)uploadmemorybufferintermediate, miplevel, scaled_width, scaled_height);
|
||||
else
|
||||
qglTexImage2D (targ, miplevel, samples, scaled_width, scaled_height, 0, glcolormode, GL_UNSIGNED_BYTE, scaled);
|
||||
qglTexImage2D (targface, miplevel, samples, scaled_width, scaled_height, 0, glcolormode, GL_UNSIGNED_BYTE, scaled);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -851,9 +851,8 @@ void R_HalfLife_WalkMeshes(entity_t *rent, batch_t *b, batch_t **batches)
|
|||
{
|
||||
hlmodelcache_t *modelc = Mod_Extradata(rent->model);
|
||||
hlmodel_t model;
|
||||
int body, m, v;
|
||||
int body, m;
|
||||
short *skins;
|
||||
int bgroup, cbone, lastbone;
|
||||
int batchid = 0;
|
||||
static mesh_t bmesh, *mptr = &bmesh;
|
||||
|
||||
|
|
|
@ -60,6 +60,10 @@ typedef struct mesh_s
|
|||
unsigned int vbofirstvert;
|
||||
unsigned int vbofirstelement;
|
||||
|
||||
/*
|
||||
FIXME: move most of this stuff out into a vbo struct
|
||||
*/
|
||||
|
||||
float xyz_blendw[2];
|
||||
|
||||
/*arrays used for rendering*/
|
||||
|
@ -87,8 +91,6 @@ typedef struct mesh_s
|
|||
} mesh_t;
|
||||
extern mesh_t nullmesh;
|
||||
|
||||
extern int gl_canbumpmap;
|
||||
|
||||
/*
|
||||
batches are generated for each shader/ent as required.
|
||||
once a batch is known to the backend for that frame, its shader, vbo, ent, lightmap, textures may not be changed until the frame has finished rendering. This is to potentially permit caching.
|
||||
|
@ -1019,6 +1021,8 @@ void Terr_PurgeTerrainModel(model_t *mod, qboolean lightmapsonly, qboolean light
|
|||
void *Mod_LoadTerrainInfo(model_t *mod, char *loadname); //call this after loading a bsp
|
||||
qboolean Heightmap_Trace(model_t *model, int forcehullnum, int frame, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, unsigned int contentmask, struct trace_s *trace);
|
||||
unsigned int Heightmap_PointContents(model_t *model, vec3_t axis[3], vec3_t org);
|
||||
struct fragmentdecal_s;
|
||||
void Terrain_ClipDecal(struct fragmentdecal_s *dec, float *center, float radius, model_t *model);
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -421,7 +421,7 @@ void R_SetupGL (void)
|
|||
stencilshadows |= r_shadow_realtime_world.ival && r_shadow_realtime_world_shadows.ival;
|
||||
#endif
|
||||
|
||||
if ((!stencilshadows || !gl_stencilbits) && gl_maxdist.value>=100)//gl_nv_range_clamp)
|
||||
if (1)//(!stencilshadows || !gl_stencilbits) && gl_maxdist.value>=100)//gl_nv_range_clamp)
|
||||
{
|
||||
// yfov = 2*atan((float)r_refdef.vrect.height/r_refdef.vrect.width)*180/M_PI;
|
||||
// yfov = (2.0 * tan (scr_fov.value/360*M_PI)) / screenaspect;
|
||||
|
|
|
@ -1506,6 +1506,8 @@ static program_t *Shader_LoadGeneric(char *name, int qrtype)
|
|||
FS_FreeFile(file);
|
||||
|
||||
g->prog.refs++;
|
||||
if (g->failed)
|
||||
return NULL;
|
||||
return &g->prog;
|
||||
}
|
||||
else
|
||||
|
@ -1644,6 +1646,7 @@ struct shader_field_names_s shader_unif_names[] =
|
|||
{"l_lightposition", SP_LIGHTPOSITION},
|
||||
{"l_lightcolourscale", SP_LIGHTCOLOURSCALE},
|
||||
{"l_projmatrix", SP_LIGHTPROJMATRIX},
|
||||
{"l_cubematrix", SP_LIGHTCUBEMATRIX},
|
||||
|
||||
{"e_rendertexturescale", SP_RENDERTEXTURESCALE},
|
||||
{NULL}
|
||||
|
@ -3958,7 +3961,7 @@ void Shader_DefaultScript(char *shortname, shader_t *s, const void *args)
|
|||
void Shader_DefaultBSPLM(char *shortname, shader_t *s, const void *args)
|
||||
{
|
||||
char *builtin = NULL;
|
||||
if (!builtin && r_drawflat.value)
|
||||
if (!builtin && r_drawflat.ival)
|
||||
builtin = (
|
||||
"{\n"
|
||||
"program drawflat_wall\n"
|
||||
|
@ -4158,6 +4161,7 @@ char *Shader_DefaultBSPWater(char *shortname)
|
|||
case 2: //refraction of the underwater surface, with a fresnel
|
||||
return (
|
||||
"{\n"
|
||||
"surfaceparm nodlight\n"
|
||||
"{\n"
|
||||
"map $refraction\n"
|
||||
"}\n"
|
||||
|
@ -4170,9 +4174,26 @@ char *Shader_DefaultBSPWater(char *shortname)
|
|||
"program altwater#FRESNEL=4\n"
|
||||
"}\n"
|
||||
);
|
||||
case 3: //ripples
|
||||
case 3: //reflections
|
||||
return (
|
||||
"{\n"
|
||||
"surfaceparm nodlight\n"
|
||||
"{\n"
|
||||
"map $refraction\n"
|
||||
"}\n"
|
||||
"{\n"
|
||||
"map $normalmap\n"
|
||||
"}\n"
|
||||
"{\n"
|
||||
"map $reflection\n"
|
||||
"}\n"
|
||||
"program altwater#REFLECT#FRESNEL=4\n"
|
||||
"}\n"
|
||||
);
|
||||
case 4: //ripples
|
||||
return (
|
||||
"{\n"
|
||||
"surfaceparm nodlight\n"
|
||||
"{\n"
|
||||
"map $refraction\n"
|
||||
"}\n"
|
||||
|
@ -4188,9 +4209,10 @@ char *Shader_DefaultBSPWater(char *shortname)
|
|||
"program altwater#RIPPLEMAP#FRESNEL=4\n"
|
||||
"}\n"
|
||||
);
|
||||
case 4: //reflections
|
||||
case 5: //ripples+reflections
|
||||
return (
|
||||
"{\n"
|
||||
"surfaceparm nodlight\n"
|
||||
"{\n"
|
||||
"map $refraction\n"
|
||||
"}\n"
|
||||
|
|
|
@ -6,6 +6,9 @@ There is no screen-space culling of lit surfaces.
|
|||
model meshes are interpolated multiple times per frame
|
||||
*/
|
||||
|
||||
//#define DBG_COLOURNOTDEPTH
|
||||
|
||||
|
||||
#if defined(GLQUAKE) || defined(D3DQUAKE)
|
||||
#ifdef RTLIGHTS
|
||||
|
||||
|
@ -25,11 +28,14 @@ void D3DBE_RenderShadowBuffer(unsigned int numverts, IDirect3DVertexBuffer9 *vbu
|
|||
#endif
|
||||
void GLBE_RenderShadowBuffer(unsigned int numverts, int vbo, vecV_t *verts, unsigned numindicies, int ibo, index_t *indicies);
|
||||
|
||||
static void SHM_Shutdown(void);
|
||||
|
||||
#define SHADOWMAP_SIZE 512
|
||||
|
||||
#define PROJECTION_DISTANCE (float)(dl->radius*2)//0x7fffffff
|
||||
|
||||
#define nearplane (16)
|
||||
#define nearplane (4)
|
||||
static texid_t shadowmap[2];
|
||||
|
||||
static int shadow_fbo_id;
|
||||
static int crepuscular_fbo_id;
|
||||
|
@ -58,6 +64,16 @@ void Sh_Shutdown(void)
|
|||
qglDeleteRenderbuffersEXT(1, &shadow_fbo_id);
|
||||
shadow_fbo_id = 0;
|
||||
}
|
||||
if (shadowmap[0].num)
|
||||
{
|
||||
R_DestroyTexture(shadowmap[0]);
|
||||
shadowmap[0] = r_nulltex;
|
||||
}
|
||||
if (shadowmap[1].num)
|
||||
{
|
||||
R_DestroyTexture(shadowmap[1]);
|
||||
shadowmap[1] = r_nulltex;
|
||||
}
|
||||
if (crepuscular_texture_id.num)
|
||||
{
|
||||
R_DestroyTexture(crepuscular_texture_id);
|
||||
|
@ -69,6 +85,8 @@ void Sh_Shutdown(void)
|
|||
crepuscular_fbo_id = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
SHM_Shutdown();
|
||||
}
|
||||
|
||||
|
||||
|
@ -968,6 +986,14 @@ static struct {
|
|||
int *edgeuses; /*negative for back sides, so 0 means unused or used equally on both sides*/
|
||||
} cv;
|
||||
|
||||
static void SHM_Shutdown(void)
|
||||
{
|
||||
free(cv.tris);
|
||||
free(cv.edges);
|
||||
free(cv.points);
|
||||
memset(&cv, 0, sizeof(cv));
|
||||
}
|
||||
|
||||
#define VERT_POS_EPSILON (1.0f/32)
|
||||
static int SHM_ComposeVolume_FindVert(float *vert)
|
||||
{
|
||||
|
@ -1233,6 +1259,7 @@ static struct shadowmesh_s *SHM_BuildShadowMesh(dlight_t *dl, unsigned char *lvi
|
|||
|
||||
firstedge=0;
|
||||
|
||||
if (cl.worldmodel->type == mod_brush)
|
||||
switch(cl.worldmodel->fromgame)
|
||||
{
|
||||
case fg_quake:
|
||||
|
@ -1778,6 +1805,34 @@ static qboolean Sh_ScissorForBox(vec3_t mins, vec3_t maxs, vrect_t *r)
|
|||
#endif
|
||||
|
||||
#ifdef GLQUAKE
|
||||
#ifdef DBG_COLOURNOTDEPTH
|
||||
void GL_BeginRenderBuffer_DepthOnly(texid_t depthtexture)
|
||||
{
|
||||
if (gl_config.ext_framebuffer_objects)
|
||||
{
|
||||
if (!shadow_fbo_id)
|
||||
{
|
||||
int drb;
|
||||
qglGenFramebuffersEXT(1, &shadow_fbo_id);
|
||||
qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, shadow_fbo_id);
|
||||
|
||||
//create an unnamed depth buffer
|
||||
// qglGenRenderbuffersEXT(1, &drb);
|
||||
// qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, drb);
|
||||
// qglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24_ARB, SHADOWMAP_SIZE*3, SHADOWMAP_SIZE*2);
|
||||
// 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, shadow_fbo_id);
|
||||
|
||||
if (TEXVALID(depthtexture))
|
||||
qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, depthtexture.num, 0);
|
||||
}
|
||||
}
|
||||
#else
|
||||
void GL_BeginRenderBuffer_DepthOnly(texid_t depthtexture)
|
||||
{
|
||||
if (gl_config.ext_framebuffer_objects)
|
||||
|
@ -1796,6 +1851,7 @@ void GL_BeginRenderBuffer_DepthOnly(texid_t depthtexture)
|
|||
qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, depthtexture.num, 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
void GL_EndRenderBuffer_DepthOnly(texid_t depthtexture, int texsize)
|
||||
{
|
||||
if (gl_config.ext_framebuffer_objects)
|
||||
|
@ -1812,74 +1868,86 @@ void GL_EndRenderBuffer_DepthOnly(texid_t depthtexture, int texsize)
|
|||
static void Sh_GenShadowFace(dlight_t *l, shadowmesh_t *smesh, int face, float proj[16])
|
||||
{
|
||||
qboolean oxv;
|
||||
float mvm[16], sav[16];
|
||||
vec3_t t1,t2;
|
||||
vec3_t t1,t2, t3;
|
||||
texture_t *tex;
|
||||
int tno;
|
||||
|
||||
int smsize = SHADOWMAP_SIZE;
|
||||
|
||||
// qglDepthRange(0, 1);
|
||||
|
||||
if (l->fov)
|
||||
qglViewport (0, 0, smsize, smsize);
|
||||
else
|
||||
qglViewport (((face/2)*smsize)/3, ((face&1)*smsize)/2, smsize/3, smsize/2);
|
||||
{
|
||||
qglViewport ((face%3 * smsize), ((face>=3)*smsize), smsize, smsize);
|
||||
}
|
||||
|
||||
switch(face)
|
||||
{
|
||||
case 0:
|
||||
//forward
|
||||
Matrix4x4_CM_ModelViewMatrixFromAxis(mvm, l->axis[0], l->axis[1], l->axis[2], l->origin);
|
||||
//+x - forward
|
||||
Matrix4x4_CM_ModelViewMatrixFromAxis(r_refdef.m_view, l->axis[0], l->axis[1], l->axis[2], l->origin);
|
||||
r_refdef.flipcull = false;
|
||||
break;
|
||||
case 1:
|
||||
//back
|
||||
//+y - right
|
||||
VectorNegate(l->axis[0], t1);
|
||||
VectorNegate(l->axis[1], t2);
|
||||
Matrix4x4_CM_ModelViewMatrixFromAxis(mvm, t1, t2, l->axis[2], l->origin);
|
||||
Matrix4x4_CM_ModelViewMatrixFromAxis(r_refdef.m_view, t2, t1, l->axis[2], l->origin);
|
||||
r_refdef.flipcull = true;
|
||||
break;
|
||||
case 2:
|
||||
//left
|
||||
VectorNegate(l->axis[1], t1);
|
||||
VectorNegate(l->axis[0], t2);
|
||||
Matrix4x4_CM_ModelViewMatrixFromAxis(mvm, l->axis[1], t2, l->axis[2], l->origin);
|
||||
//+z - down
|
||||
VectorNegate(l->axis[0], t1);
|
||||
VectorNegate(l->axis[2], t2);
|
||||
Matrix4x4_CM_ModelViewMatrixFromAxis(r_refdef.m_view, t2, l->axis[1], t1, l->origin);
|
||||
r_refdef.flipcull = true;
|
||||
break;
|
||||
case 3:
|
||||
//right
|
||||
VectorNegate(l->axis[1], t1);
|
||||
Matrix4x4_CM_ModelViewMatrixFromAxis(mvm, t1, l->axis[0], l->axis[2], l->origin);
|
||||
//-x - back
|
||||
VectorNegate(l->axis[0], t1);
|
||||
VectorNegate(l->axis[1], t2);
|
||||
VectorNegate(l->axis[2], t3);
|
||||
Matrix4x4_CM_ModelViewMatrixFromAxis(r_refdef.m_view, t1, l->axis[1], l->axis[2], l->origin);
|
||||
r_refdef.flipcull = true;
|
||||
break;
|
||||
case 4:
|
||||
//up
|
||||
//-y - left
|
||||
VectorNegate(l->axis[1], t1);
|
||||
VectorNegate(l->axis[0], t2);
|
||||
Matrix4x4_CM_ModelViewMatrixFromAxis(mvm, l->axis[2], l->axis[1], t2, l->origin);
|
||||
Matrix4x4_CM_ModelViewMatrixFromAxis(r_refdef.m_view, l->axis[1], t2, l->axis[2], l->origin);
|
||||
r_refdef.flipcull = false;
|
||||
break;
|
||||
case 5:
|
||||
//down
|
||||
VectorNegate(l->axis[2], t1);
|
||||
Matrix4x4_CM_ModelViewMatrixFromAxis(mvm, t1, l->axis[1], l->axis[0], l->origin);
|
||||
//-z - up
|
||||
VectorNegate(l->axis[0], t2);
|
||||
Matrix4x4_CM_ModelViewMatrixFromAxis(r_refdef.m_view, l->axis[2], l->axis[1], t2, l->origin);
|
||||
r_refdef.flipcull = false;
|
||||
break;
|
||||
}
|
||||
GL_CullFace(0);
|
||||
R_SetFrustum(proj, r_refdef.m_view);
|
||||
|
||||
qglMatrixMode(GL_MODELVIEW);
|
||||
memcpy(sav, r_refdef.m_view, sizeof(r_refdef.m_view));
|
||||
memcpy(r_refdef.m_view, mvm, sizeof(r_refdef.m_view));
|
||||
qglLoadMatrixf(mvm);
|
||||
|
||||
R_SetFrustum(proj, mvm);
|
||||
|
||||
/* if (smesh)
|
||||
for (tno = 0; tno < smesh->numsurftextures; tno++)
|
||||
{
|
||||
m = NULL;
|
||||
if (!smesh->litsurfs[tno].count)
|
||||
continue;
|
||||
tex = cl.worldmodel->textures[tno];
|
||||
BE_DrawMesh_List(tex->shader, smesh->litsurfs[tno].count, smesh->litsurfs[tno].s, &tex->vbo, &tex->shader->defaulttextures, 0);
|
||||
}
|
||||
*/
|
||||
#ifdef DBG_COLOURNOTDEPTH
|
||||
BE_SelectMode(BEM_STANDARD);
|
||||
#else
|
||||
BE_SelectMode(BEM_DEPTHONLY);
|
||||
#endif
|
||||
/*shadow meshes are always drawn as an external view*/
|
||||
oxv = r_refdef.externalview;
|
||||
r_refdef.externalview = true;
|
||||
|
||||
BE_SelectEntity(&r_worldentity);
|
||||
|
||||
for (tno = 0; tno < smesh->numbatches; tno++)
|
||||
{
|
||||
if (!smesh->batches[tno].count)
|
||||
continue;
|
||||
tex = cl.worldmodel->shadowbatches[tno].tex;
|
||||
if (tex->shader->flags & SHADER_NODLIGHT)
|
||||
continue;
|
||||
BE_DrawMesh_List(tex->shader, smesh->batches[tno].count, smesh->batches[tno].s, cl.worldmodel->shadowbatches[tno].vbo, &tex->shader->defaulttextures, 0);
|
||||
}
|
||||
|
||||
switch(qrenderer)
|
||||
{
|
||||
#ifdef GLQUAKE
|
||||
|
@ -1893,9 +1961,10 @@ static void Sh_GenShadowFace(dlight_t *l, shadowmesh_t *smesh, int face, float p
|
|||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
r_refdef.externalview = oxv;
|
||||
|
||||
if (0)
|
||||
/*
|
||||
{
|
||||
int i;
|
||||
static float depth[SHADOWMAP_SIZE*SHADOWMAP_SIZE];
|
||||
|
@ -1908,6 +1977,7 @@ static void Sh_GenShadowFace(dlight_t *l, shadowmesh_t *smesh, int face, float p
|
|||
else
|
||||
*((unsigned int*)depth+i) = 0xff000000|((((unsigned char)(int)(depth[i]*128)))*0x10101);
|
||||
}
|
||||
|
||||
qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
|
||||
smsize, smsize, 0,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, depth);
|
||||
|
@ -1917,65 +1987,99 @@ static void Sh_GenShadowFace(dlight_t *l, shadowmesh_t *smesh, int face, float p
|
|||
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||
}
|
||||
|
||||
memcpy(r_refdef.m_view, sav, sizeof(r_refdef.m_view));
|
||||
*/
|
||||
}
|
||||
|
||||
void Sh_GenShadowMap (dlight_t *l, qbyte *lvis)
|
||||
{
|
||||
int f;
|
||||
int smsize = SHADOWMAP_SIZE;
|
||||
float proj[16];
|
||||
|
||||
float oproj[16], oview[16];
|
||||
shadowmesh_t *smesh;
|
||||
int isspot = (l->fov != 0);
|
||||
|
||||
if (!TEXVALID(l->stexture))
|
||||
if (!TEXVALID(shadowmap[isspot]))
|
||||
{
|
||||
l->stexture = GL_AllocNewTexture("***shadowmap***", smsize, smsize);
|
||||
if (isspot)
|
||||
{
|
||||
shadowmap[isspot] = GL_AllocNewTexture("***shadowmap***", smsize, smsize);
|
||||
GL_MTBind(0, GL_TEXTURE_2D, shadowmap[isspot]);
|
||||
#ifdef DBG_COLOURNOTDEPTH
|
||||
qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, smsize, smsize, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
#else
|
||||
qglTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32_ARB, smsize, smsize, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
shadowmap[isspot] = GL_AllocNewTexture("***shadowmap***", smsize*3, smsize*2);
|
||||
GL_MTBind(0, GL_TEXTURE_2D, shadowmap[isspot]);
|
||||
#ifdef DBG_COLOURNOTDEPTH
|
||||
qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, smsize*3, smsize*2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
#else
|
||||
qglTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32_ARB, smsize*3, smsize*2, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
GL_MTBind(0, GL_TEXTURE_2D, l->stexture);
|
||||
qglTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32_ARB, smsize, smsize, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
|
||||
// qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, smsize, smsize, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||
#if 1//def DBG_COLOURNOTDEPTH
|
||||
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
#else
|
||||
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
#endif
|
||||
|
||||
//in case we're using shadow samplers
|
||||
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
|
||||
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
|
||||
qglTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);
|
||||
}
|
||||
|
||||
smesh = SHM_BuildShadowMesh(l, lvis, NULL, true);
|
||||
|
||||
/*polygon offsets. urgh.*/
|
||||
qglEnable(GL_POLYGON_OFFSET_FILL);
|
||||
qglPolygonOffset(5, 25);
|
||||
BE_SetupForShadowMap();
|
||||
|
||||
/*set framebuffer*/
|
||||
GL_BeginRenderBuffer_DepthOnly(l->stexture);
|
||||
qglClear (GL_DEPTH_BUFFER_BIT);
|
||||
GL_BeginRenderBuffer_DepthOnly(shadowmap[isspot]);
|
||||
BE_SetupForShadowMap(shadowmap[isspot]);
|
||||
|
||||
qglViewport(0, 0, smsize*3, smsize*2);
|
||||
qglClear (GL_DEPTH_BUFFER_BIT);
|
||||
#ifdef DBG_COLOURNOTDEPTH
|
||||
qglClearColor(0,1,0,1);
|
||||
qglClear (GL_COLOR_BUFFER_BIT);
|
||||
#endif
|
||||
|
||||
memcpy(oproj, r_refdef.m_projection, sizeof(oproj));
|
||||
memcpy(oview, r_refdef.m_view, sizeof(oview));
|
||||
if (l->fov)
|
||||
{
|
||||
Matrix4x4_CM_Projection_Far(proj, l->fov, l->fov, nearplane, l->radius);
|
||||
Matrix4x4_CM_Projection_Far(r_refdef.m_projection, l->fov, l->fov, nearplane, l->radius);
|
||||
qglMatrixMode(GL_PROJECTION);
|
||||
qglLoadMatrixf(proj);
|
||||
qglLoadMatrixf(r_refdef.m_projection);
|
||||
qglMatrixMode(GL_MODELVIEW);
|
||||
|
||||
/*single face*/
|
||||
Sh_GenShadowFace(l, smesh, 0, proj);
|
||||
Sh_GenShadowFace(l, smesh, 0, r_refdef.m_projection);
|
||||
}
|
||||
else
|
||||
{
|
||||
Matrix4x4_CM_Projection_Far(proj, 90, 90, nearplane, l->radius);
|
||||
Matrix4x4_CM_Projection_Far(r_refdef.m_projection, 90, 90, nearplane, l->radius);
|
||||
qglMatrixMode(GL_PROJECTION);
|
||||
qglLoadMatrixf(proj);
|
||||
qglLoadMatrixf(r_refdef.m_projection);
|
||||
qglMatrixMode(GL_MODELVIEW);
|
||||
|
||||
/*generate faces*/
|
||||
for (f = 0; f < 6; f++)
|
||||
{
|
||||
Sh_GenShadowFace(l, smesh, f, proj);
|
||||
Sh_GenShadowFace(l, smesh, f, r_refdef.m_projection);
|
||||
}
|
||||
}
|
||||
/*end framebuffer*/
|
||||
GL_EndRenderBuffer_DepthOnly(l->stexture, smsize);
|
||||
GL_EndRenderBuffer_DepthOnly(shadowmap[isspot], smsize);
|
||||
|
||||
memcpy(r_refdef.m_view, oview, sizeof(r_refdef.m_view));
|
||||
memcpy(r_refdef.m_projection, oproj, sizeof(r_refdef.m_projection));
|
||||
|
||||
qglDisable(GL_POLYGON_OFFSET_FILL);
|
||||
|
||||
|
@ -1990,20 +2094,8 @@ void Sh_GenShadowMap (dlight_t *l, qbyte *lvis)
|
|||
R_SetFrustum(r_refdef.m_projection, r_refdef.m_view);
|
||||
}
|
||||
|
||||
static float shadowprojectionbias[16] =
|
||||
{
|
||||
0.5f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.5f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.5f, 0.0f,
|
||||
0.5f, 0.5f, 0.4993f, 1.0f
|
||||
};
|
||||
|
||||
static void Sh_DrawShadowMapLight(dlight_t *l, vec3_t colour, qbyte *vvis)
|
||||
{
|
||||
float t[16];
|
||||
float bp[16];
|
||||
float proj[16], view[16];
|
||||
vec3_t biasorg;
|
||||
int ve;
|
||||
vec3_t mins, maxs;
|
||||
qbyte *lvis;
|
||||
|
@ -2030,86 +2122,49 @@ static void Sh_DrawShadowMapLight(dlight_t *l, vec3_t colour, qbyte *vvis)
|
|||
return;
|
||||
}
|
||||
|
||||
if (l->worldshadowmesh)
|
||||
{
|
||||
lvis = l->worldshadowmesh->litleaves;
|
||||
//fixme: check head node first?
|
||||
if (!Sh_LeafInView(l->worldshadowmesh->litleaves, vvis))
|
||||
{
|
||||
bench.numpvsculled++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (vvis)
|
||||
{
|
||||
int leaf;
|
||||
leaf = cl.worldmodel->funcs.LeafnumForPoint(cl.worldmodel, l->origin);
|
||||
lvis = cl.worldmodel->funcs.LeafPVS(cl.worldmodel, leaf, lvisb, sizeof(lvisb));
|
||||
if (!Sh_VisOverlaps(lvis, vvis)) //The two viewing areas do not intersect.
|
||||
if (l->worldshadowmesh)
|
||||
{
|
||||
bench.numpvsculled++;
|
||||
return;
|
||||
lvis = l->worldshadowmesh->litleaves;
|
||||
//fixme: check head node first?
|
||||
if (!Sh_LeafInView(l->worldshadowmesh->litleaves, vvis))
|
||||
{
|
||||
bench.numpvsculled++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int leaf;
|
||||
leaf = cl.worldmodel->funcs.LeafnumForPoint(cl.worldmodel, l->origin);
|
||||
lvis = cl.worldmodel->funcs.LeafPVS(cl.worldmodel, leaf, lvisb, sizeof(lvisb));
|
||||
if (!Sh_VisOverlaps(lvis, vvis)) //The two viewing areas do not intersect.
|
||||
{
|
||||
bench.numpvsculled++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
qglDisable(GL_SCISSOR_TEST);
|
||||
|
||||
Sh_GenShadowMap(l, lvis);
|
||||
|
||||
if (l->fov)
|
||||
Matrix4x4_CM_Projection_Far(proj, l->fov, l->fov, nearplane, l->radius);
|
||||
else
|
||||
Matrix4x4_CM_Projection_Far(proj, 90, 90, nearplane, l->radius);
|
||||
VectorMA(l->origin, 0, l->axis[0], biasorg);
|
||||
Matrix4x4_CM_ModelViewMatrixFromAxis(view, l->axis[0], l->axis[1], l->axis[2], l->origin);
|
||||
|
||||
//bp = shadowprojectionbias*proj*view;
|
||||
Matrix4_Multiply(shadowprojectionbias, proj, t);
|
||||
Matrix4_Multiply(t, view, bp);
|
||||
|
||||
t[0] = bp[0];
|
||||
t[1] = bp[4];
|
||||
t[2] = bp[8];
|
||||
t[3] = bp[12];
|
||||
t[4] = bp[1];
|
||||
t[5] = bp[5];
|
||||
t[6] = bp[9];
|
||||
t[7] = bp[13];
|
||||
t[8] = bp[2];
|
||||
t[9] = bp[6];
|
||||
t[10] = bp[10];
|
||||
t[11] = bp[14];
|
||||
t[12] = bp[3];
|
||||
t[13] = bp[7];
|
||||
t[14] = bp[11];
|
||||
t[15] = bp[15];
|
||||
|
||||
bench.numlights++;
|
||||
|
||||
//may as well use scissors
|
||||
Sh_Scissor(rect);
|
||||
qglEnable(GL_STENCIL_TEST);
|
||||
|
||||
qglMatrixMode(GL_TEXTURE);
|
||||
GL_MTBind(7, GL_TEXTURE_2D, l->stexture);
|
||||
|
||||
// qglEnable(GL_TEXTURE_2D);
|
||||
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
|
||||
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
|
||||
qglTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);
|
||||
qglLoadMatrixf(bp);
|
||||
qglMatrixMode(GL_MODELVIEW);
|
||||
|
||||
GL_SelectTexture(0);
|
||||
qglEnable(GL_SCISSOR_TEST);
|
||||
|
||||
ve = 0;
|
||||
|
||||
BE_SelectEntity(&r_worldentity);
|
||||
|
||||
GLBE_SelectDLight(l, colour);
|
||||
BE_SelectMode(l->fov?BEM_SMAPLIGHTSPOT:BEM_SMAPLIGHT);
|
||||
Sh_DrawEntLighting(l, colour);
|
||||
|
||||
GL_SelectTexture(7);
|
||||
qglDisable(GL_TEXTURE_2D);
|
||||
qglMatrixMode(GL_TEXTURE);
|
||||
qglLoadIdentity();
|
||||
qglMatrixMode(GL_MODELVIEW);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -2871,6 +2926,7 @@ void Sh_DrawLights(qbyte *vis)
|
|||
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;
|
||||
extern cvar_t r_shadow_shadowmapping;
|
||||
|
||||
if (!r_shadow_realtime_world.ival && !r_shadow_realtime_dlight.ival)
|
||||
{
|
||||
|
@ -2942,7 +2998,7 @@ void Sh_DrawLights(qbyte *vis)
|
|||
{
|
||||
Sh_DrawShadowlessLight(dl, colour, vis);
|
||||
}
|
||||
else if (dl->flags & LFLAG_SHADOWMAP)
|
||||
else if ((dl->flags & LFLAG_SHADOWMAP) || dl->fov || r_shadow_shadowmapping.ival)
|
||||
{
|
||||
#ifdef GLQUAKE
|
||||
Sh_DrawShadowMapLight(dl, colour, vis);
|
||||
|
|
|
@ -666,9 +666,40 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name))
|
|||
qglUnmapBufferARB = (void *)getglext("glUnmapBufferARB");
|
||||
}
|
||||
|
||||
if (0 && !gl_config.nofixedfunc)
|
||||
if (Cvar_Get("gl_blacklist_debug_glsl", "0", CVAR_RENDERERLATCH, "gl blacklists")->ival && !gl_config.nofixedfunc)
|
||||
{
|
||||
Con_Printf(CON_NOTICE "GLSL disabled\n");
|
||||
gl_config.arb_shader_objects = false;
|
||||
qglCreateProgramObjectARB = NULL;
|
||||
qglDeleteProgramObject_ = NULL;
|
||||
qglDeleteShaderObject_ = NULL;
|
||||
qglUseProgramObjectARB = NULL;
|
||||
qglCreateShaderObjectARB = NULL;
|
||||
qglGetProgramParameteriv_ = NULL;
|
||||
qglGetShaderParameteriv_ = NULL;
|
||||
qglAttachObjectARB = NULL;
|
||||
qglGetProgramInfoLog_ = NULL;
|
||||
qglGetShaderInfoLog_ = NULL;
|
||||
qglShaderSourceARB = NULL;
|
||||
qglCompileShaderARB = NULL;
|
||||
qglLinkProgramARB = NULL;
|
||||
qglBindAttribLocationARB = NULL;
|
||||
qglGetAttribLocationARB = NULL;
|
||||
qglVertexAttribPointer = NULL;
|
||||
qglGetVertexAttribiv = NULL;
|
||||
qglEnableVertexAttribArray = NULL;
|
||||
qglDisableVertexAttribArray = NULL;
|
||||
qglGetUniformLocationARB = NULL;
|
||||
qglUniformMatrix4fvARB = NULL;
|
||||
qglUniformMatrix3x4fv = NULL;
|
||||
qglUniformMatrix4x3fv = NULL;
|
||||
qglUniform4fARB = NULL;
|
||||
qglUniform4fvARB = NULL;
|
||||
qglUniform3fARB = NULL;
|
||||
qglUniform3fvARB = NULL;
|
||||
qglUniform2fvARB = NULL;
|
||||
qglUniform1iARB = NULL;
|
||||
qglUniform1fARB = NULL;
|
||||
}
|
||||
// glslang
|
||||
//the gf2 to gf4 cards emulate vertex_shader and thus supports shader_objects.
|
||||
|
|
|
@ -27,6 +27,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include "shader.h"
|
||||
#include <commctrl.h>
|
||||
|
||||
void STT_Event(void);
|
||||
|
||||
#ifndef SetWindowLongPtr //yes its a define, for unicode support
|
||||
#define SetWindowLongPtr SetWindowLong
|
||||
#endif
|
||||
|
@ -1206,7 +1208,9 @@ qboolean VID_AttachGL (rendererstate_t *info)
|
|||
else
|
||||
attribs[i+1] |= WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
|
||||
attribs[i] = WGL_CONTEXT_PROFILE_MASK_ARB;
|
||||
i+=2;
|
||||
//WGL_CONTEXT_PROFILE_MASK_ARB is ignored if < 3.2 - however, nvidia do not agree and return errors
|
||||
if (atof(ver) >= 3.2 || vid_gl_context_es2.ival)
|
||||
i+=2;
|
||||
|
||||
attribs[i] = 0;
|
||||
|
||||
|
@ -1924,6 +1928,10 @@ LONG WINAPI GLMainWndProc (
|
|||
IN_RawInput_Read((HANDLE)lParam);
|
||||
break;
|
||||
|
||||
case WM_USER:
|
||||
STT_Event();
|
||||
break;
|
||||
|
||||
case WM_GETMINMAXINFO:
|
||||
{
|
||||
RECT windowrect;
|
||||
|
|
|
@ -90,8 +90,8 @@ void ClearBounds (vec3_t mins, vec3_t maxs);
|
|||
#define GL_QUADS (Con_Printf("GL_QUADS was used"),0)
|
||||
|
||||
|
||||
#define GL_PROJECTION (Con_Printf("GL_QUADS was used"),0)
|
||||
#define GL_MODELVIEW (Con_Printf("GL_QUADS was used"),0)
|
||||
#define GL_PROJECTION (Con_Printf("GL_PROJECTION was used"),0)
|
||||
#define GL_MODELVIEW (Con_Printf("GL_MODELVIEW was used"),0)
|
||||
#define GL_CLIP_PLANE0 (Con_Printf("GL_CLIP_PLANE0 was used"),0)
|
||||
#define GL_MODULATE (Con_Printf("GL_MODULATE was used"),0)
|
||||
#define GL_FLAT (Con_Printf("GL_FLAT was used"),0)
|
||||
|
|
|
@ -902,7 +902,13 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
//s0=diffuse, s1=normal, s2=specular, s3=shadowmap
|
||||
//custom modifiers:
|
||||
//PCF(shadowmap)
|
||||
//CUBE(projected cubemap)
|
||||
//CUBEPROJ(projected cubemap)
|
||||
//SPOT(projected circle
|
||||
//CUBESHADOW
|
||||
|
||||
"#if 0 && defined(GL_ARB_texture_gather) && defined(PCF) \n"
|
||||
"#extension GL_ARB_texture_gather : enable\n"
|
||||
"#endif\n"
|
||||
|
||||
|
||||
"varying vec2 tcbase;\n"
|
||||
|
@ -910,10 +916,13 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
"#if defined(SPECULAR) || defined(OFFSETMAPPING)\n"
|
||||
"varying vec3 eyevector;\n"
|
||||
"#endif\n"
|
||||
"#if defined(PCF) || defined(CUBE)\n"
|
||||
"varying vec4 vshadowcoord;\n"
|
||||
"#if defined(PCF) || defined(CUBEPROJ)\n"
|
||||
"varying vec4 vtexprojcoord;\n"
|
||||
"uniform mat4 l_cubematrix;\n"
|
||||
"#ifndef SPOT\n"
|
||||
"uniform mat4 l_projmatrix;\n"
|
||||
"#endif\n"
|
||||
"#endif\n"
|
||||
"#ifdef VERTEX_SHADER\n"
|
||||
"#include \"sys/skeletal.h\"\n"
|
||||
"uniform vec3 l_lightposition;\n"
|
||||
|
@ -936,33 +945,142 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
"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"
|
||||
"#if defined(PCF) || defined(SPOT) || defined(PROJECTION)\n"
|
||||
//for texture projections/shadowmapping on dlights
|
||||
"vtexprojcoord = (l_cubematrix*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"
|
||||
"#ifdef CUBEPROJ\n"
|
||||
"uniform samplerCube s_t3;\n"
|
||||
"#endif\n"
|
||||
"#ifdef PCF\n"
|
||||
"#ifdef CUBE\n"
|
||||
"uniform samplerCubeShadow s_t7;\n"
|
||||
"#ifdef CUBESHADOW\n"
|
||||
"uniform samplerCubeShadow s_t4;\n"
|
||||
"#else\n"
|
||||
"uniform sampler2DShadow s_t7;\n"
|
||||
"#if 0//def GL_ARB_texture_gather\n"
|
||||
"uniform sampler2D s_t4;\n"
|
||||
"#else\n"
|
||||
"uniform sampler2DShadow s_t4;\n"
|
||||
"#endif\n"
|
||||
"#endif\n"
|
||||
"#endif\n"
|
||||
|
||||
|
||||
"uniform float l_lightradius;\n"
|
||||
"uniform vec3 l_lightcolour;\n"
|
||||
"uniform vec3 l_lightcolourscale;\n"
|
||||
|
||||
|
||||
|
||||
"#ifdef PCF\n"
|
||||
//#define shadow2DProj(t,c) (vec2(1.0,1.0))
|
||||
//#define shadow2DProj(t,c) texture2DProj(t,c).rg
|
||||
|
||||
"float ShadowmapFilter(void)\n"
|
||||
"{\n"
|
||||
"#ifdef SPOT\n"
|
||||
"const vec3 texscale = vec3(1.0/512.0, 1.0/512.0, 1.0);\n"
|
||||
"#else\n"
|
||||
"const vec3 texscale = vec3(1.0/(512.0*3.0), 1.0/(512.0*2.0), 1.0);\n"
|
||||
"#endif\n"
|
||||
|
||||
//dehomogonize input
|
||||
"vec3 shadowcoord = (vtexprojcoord.xyz / vtexprojcoord.w);\n"
|
||||
|
||||
"#ifdef CUBESHADOW\n"
|
||||
// vec3 shadowcoord = vshadowcoord.xyz / vshadowcoord.w;
|
||||
// #define dosamp(x,y) shadowCube(s_t4, shadowcoord + vec2(x,y)*texscale.xy).r
|
||||
"#else\n"
|
||||
|
||||
"#ifdef SPOT\n"
|
||||
//bias it. don't bother figuring out which side or anything, its not needed
|
||||
//l_projmatrix contains the light's projection matrix so no other magic needed
|
||||
"shadowcoord.xyz = (shadowcoord.xyz + vec3(1.0, 1.0, 1.0)) * vec3(0.5, 0.5, 0.5);\n"
|
||||
"#else\n"
|
||||
//figure out which axis to use
|
||||
//texture is arranged thusly:
|
||||
//forward left up
|
||||
//back right down
|
||||
"vec3 dir = abs(shadowcoord);\n"
|
||||
//assume z is the major axis (ie: forward from the light)
|
||||
"vec3 t = shadowcoord;\n"
|
||||
"float ma = dir.z;\n"
|
||||
"vec4 axis = vec4(1.0, 1.0, 1.0, 0.0);\n"
|
||||
"if (dir.x > ma)\n"
|
||||
"{\n"
|
||||
"ma = dir.x;\n"
|
||||
"t = shadowcoord.zyx;\n"
|
||||
"axis.x = 3.0;\n"
|
||||
"}\n"
|
||||
"if (dir.y > ma)\n"
|
||||
"{\n"
|
||||
"ma = dir.y;\n"
|
||||
"t = shadowcoord.xzy;\n"
|
||||
"axis.x = 5.0;\n"
|
||||
"}\n"
|
||||
"if (t.z > 0.0)\n"
|
||||
"{\n"
|
||||
"axis.y = 3.0;\n"
|
||||
"t.z = -t.z;\n"
|
||||
"}\n"
|
||||
|
||||
|
||||
//we also need to pass the result through the light's projection matrix too
|
||||
"vec4 nsc =l_projmatrix*vec4(t, 1.0);\n"
|
||||
"shadowcoord = (nsc.xyz / nsc.w);\n"
|
||||
|
||||
//now bias and relocate it
|
||||
"shadowcoord = (shadowcoord + axis.xyz) * vec3(0.5/3.0, 0.5/2.0, 0.5);\n"
|
||||
"#endif\n"
|
||||
|
||||
"#if 0//def GL_ARB_texture_gather\n"
|
||||
"vec2 ipart, fpart;\n"
|
||||
"#define dosamp(x,y) textureGatherOffset(s_t4, ipart.xy, vec2(x,y)))\n"
|
||||
"vec4 tl = step(shadowcoord.z, dosamp(-1.0, -1.0));\n"
|
||||
"vec4 bl = step(shadowcoord.z, dosamp(-1.0, 1.0));\n"
|
||||
"vec4 tr = step(shadowcoord.z, dosamp(1.0, -1.0));\n"
|
||||
"vec4 br = step(shadowcoord.z, dosamp(1.0, 1.0));\n"
|
||||
//we now have 4*4 results, woo
|
||||
//we can just average them for 1/16th precision, but that's still limited graduations
|
||||
//the middle four pixels are 'full strength', but we interpolate the sides to effectively give 3*3
|
||||
"vec4 col = vec4(tl.ba, tr.ba) + vec4(bl.rg, br.rg) + //middle two rows are full strength\n"
|
||||
"mix(vec4(tl.rg, tr.rg), vec4(bl.ba, br.ba), fpart.y); //top+bottom rows\n"
|
||||
"return dot(mix(col.rgb, col.agb, fpart.x), vec3(1.0/9.0)); //blend r+a, gb are mixed because its pretty much free and gives a nicer dot instruction instead of lots of adds.\n"
|
||||
|
||||
"#else\n"
|
||||
"#define dosamp(x,y) shadow2D(s_t4, shadowcoord.xyz + (vec3(x,y,0.0)*texscale.xyz)).r\n"
|
||||
"float s = 0.0;\n"
|
||||
"s += dosamp(-1.0, -1.0);\n"
|
||||
"s += dosamp(-1.0, 0.0);\n"
|
||||
"s += dosamp(-1.0, 1.0);\n"
|
||||
"s += dosamp(0.0, -1.0);\n"
|
||||
"s += dosamp(0.0, 0.0);\n"
|
||||
"s += dosamp(0.0, 1.0);\n"
|
||||
"s += dosamp(1.0, -1.0);\n"
|
||||
"s += dosamp(1.0, 0.0);\n"
|
||||
"s += dosamp(1.0, 1.0);\n"
|
||||
"return s/9.0;\n"
|
||||
"#endif\n"
|
||||
"#endif\n"
|
||||
"}\n"
|
||||
"#endif\n"
|
||||
|
||||
|
||||
"#ifdef OFFSETMAPPING\n"
|
||||
"#include \"sys/offsetmapping.h\"\n"
|
||||
"#endif\n"
|
||||
|
@ -987,6 +1105,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
"#ifdef BUMP\n"
|
||||
"diff = bases * (l_lightcolourscale.x + l_lightcolourscale.y * max(dot(bumps, nl), 0.0));\n"
|
||||
"#else\n"
|
||||
//we still do bumpmapping even without bumps to ensure colours are always sane. light.exe does it too.
|
||||
"diff = bases * (l_lightcolourscale.x + l_lightcolourscale.y * max(dot(vec3(0.0, 0.0, 1.0), nl), 0.0));\n"
|
||||
"#endif\n"
|
||||
|
||||
|
@ -999,54 +1118,30 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
|
||||
|
||||
|
||||
"#ifdef CUBE\n"
|
||||
"diff *= textureCube(s_t3, vshadowcoord.xyz).rgb;\n"
|
||||
"#ifdef CUBEPROJ\n"
|
||||
/*filter the colour by the cubemap projection*/
|
||||
"diff *= textureCube(s_t3, vtexprojcoord.xyz).rgb;\n"
|
||||
"#endif\n"
|
||||
|
||||
"#if defined(SPOT)\n"
|
||||
/*filter the colour by the spotlight. discard anything behind the light so we don't get a mirror image*/
|
||||
"if (vtexprojcoord.w < 0.0) discard;\n"
|
||||
"vec2 spot = ((vtexprojcoord.st)/vtexprojcoord.w);colorscale*=1.0-(dot(spot,spot));\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"
|
||||
/*filter the light by the shadowmap. logically a boolean, but we allow fractions for softer shadows*/
|
||||
//diff.rgb = (vtexprojcoord.xyz/vtexprojcoord.w) * 0.5 + 0.5;
|
||||
"colorscale *= ShadowmapFilter();\n"
|
||||
// gl_FragColor.rgb = vec3(ShadowmapFilter());
|
||||
|
||||
"#endif\n"
|
||||
|
||||
"#if defined(PROJECTION)\n"
|
||||
"l_lightcolour *= texture2d(s_t3, shadowcoord);\n"
|
||||
/*2d projection, not used*/
|
||||
// diff *= texture2d(s_t3, shadowcoord);
|
||||
"#endif\n"
|
||||
|
||||
"gl_FragColor.rgb = fog3additive(diff*colorscale*l_lightcolour);\n"
|
||||
"}\n"
|
||||
"#endif\n"
|
||||
|
@ -1107,14 +1202,17 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
"#include \"sys/fog.h\"\n"
|
||||
"varying vec2 tc;\n"
|
||||
"varying vec2 lm;\n"
|
||||
"varying vec4 vc;\n"
|
||||
|
||||
"#ifdef VERTEX_SHADER\n"
|
||||
"attribute vec2 v_texcoord;\n"
|
||||
"attribute vec2 v_lmcoord;\n"
|
||||
"attribute vec4 v_colour;\n"
|
||||
"void main (void)\n"
|
||||
"{\n"
|
||||
"tc = v_texcoord.st;\n"
|
||||
"lm = v_lmcoord.st;\n"
|
||||
"vc = v_colour;\n"
|
||||
"gl_Position = ftetransform();\n"
|
||||
"}\n"
|
||||
"#endif\n"
|
||||
|
@ -1137,7 +1235,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
"{\n"
|
||||
"vec4 m = texture2D(s_t4, lm);\n"
|
||||
|
||||
"gl_FragColor = fog4(vec4(m.aaa,1.0)*(\n"
|
||||
"gl_FragColor = fog4(vc*vec4(m.aaa,1.0)*(\n"
|
||||
"texture2D(s_t0, tc)*m.r\n"
|
||||
"+ texture2D(s_t1, tc)*m.g\n"
|
||||
"+ texture2D(s_t2, tc)*m.b\n"
|
||||
|
|
|
@ -336,6 +336,7 @@ typedef struct {
|
|||
SP_LIGHTPOSITION,
|
||||
SP_LIGHTSCREEN,
|
||||
SP_LIGHTPROJMATRIX,
|
||||
SP_LIGHTCUBEMATRIX,
|
||||
|
||||
//things that are set immediatly
|
||||
SP_FIRSTIMMEDIATE, //never set
|
||||
|
@ -556,7 +557,7 @@ void BE_GenerateProgram(shader_t *shader);
|
|||
#ifdef RTLIGHTS
|
||||
void BE_PushOffsetShadow(qboolean foobar);
|
||||
//sets up gl for depth-only FIXME
|
||||
void BE_SetupForShadowMap(void);
|
||||
void BE_SetupForShadowMap(texid_t shadowmaptex);
|
||||
//Called from shadowmapping code into backend
|
||||
void GLBE_BaseEntTextures(void);
|
||||
void D3DBE_BaseEntTextures(void);
|
||||
|
|
|
@ -3324,9 +3324,9 @@ static void QCBUILTIN PF_stuffcmd (progfuncs_t *prinst, struct globalvars_s *pr_
|
|||
|
||||
if (sv.mvdrecording)
|
||||
{
|
||||
MVDWrite_Begin (dem_single, entnum - 1, 2 + slen);
|
||||
MSG_WriteByte (&demo.dbuf->sb, svc_stufftext);
|
||||
MSG_WriteString (&demo.dbuf->sb, str);
|
||||
sizebuf_t *msg = MVDWrite_Begin (dem_single, entnum - 1, 2 + slen);
|
||||
MSG_WriteByte (msg, svc_stufftext);
|
||||
MSG_WriteString (msg, str);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -646,8 +646,8 @@ typedef struct {
|
|||
|
||||
typedef struct
|
||||
{
|
||||
demobuf_t *dbuf;
|
||||
dbuffer_t dbuffer;
|
||||
// demobuf_t *dbuf;
|
||||
// dbuffer_t dbuffer;
|
||||
sizebuf_t datagram;
|
||||
qbyte datagram_data[MSG_BUF_SIZE];
|
||||
int lastto;
|
||||
|
@ -1270,8 +1270,7 @@ typedef struct mvddest_s {
|
|||
} mvddest_t;
|
||||
void SV_MVDPings (void);
|
||||
void SV_MVD_FullClientUpdate(sizebuf_t *msg, client_t *player);
|
||||
void SV_MVDWriteToDisk(int type, int to, float time);
|
||||
qboolean MVDWrite_Begin(qbyte type, int to, int size);
|
||||
sizebuf_t *MVDWrite_Begin(qbyte type, int to, int size);
|
||||
void MVDSetMsgBuf(demobuf_t *prev,demobuf_t *cur);
|
||||
void SV_MVDStop (int reason, qboolean mvdonly);
|
||||
void SV_MVDStop_f (void);
|
||||
|
|
|
@ -1590,13 +1590,14 @@ void SV_ConSay_f(void)
|
|||
|
||||
if (sv.mvdrecording)
|
||||
{
|
||||
MVDWrite_Begin (dem_all, 0, strlen(text)+4);
|
||||
MSG_WriteByte (&demo.dbuf->sb, svc_print);
|
||||
MSG_WriteByte (&demo.dbuf->sb, PRINT_CHAT);
|
||||
sizebuf_t *msg;
|
||||
msg = MVDWrite_Begin (dem_all, 0, strlen(text)+4);
|
||||
MSG_WriteByte (msg, svc_print);
|
||||
MSG_WriteByte (msg, PRINT_CHAT);
|
||||
for (j = 0; text[j]; j++)
|
||||
MSG_WriteChar(&demo.dbuf->sb, text[j]);
|
||||
MSG_WriteChar(&demo.dbuf->sb, '\n');
|
||||
MSG_WriteChar(&demo.dbuf->sb, 0);
|
||||
MSG_WriteChar(msg, text[j]);
|
||||
MSG_WriteChar(msg, '\n');
|
||||
MSG_WriteChar(msg, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,10 +31,10 @@ void SV_MVDStop_f (void);
|
|||
#define demo_size_padding 0x1000
|
||||
|
||||
|
||||
#define MIN_MVD_MEMORY 0x100000
|
||||
#define MAXSIZE (demobuffer->end < demobuffer->last ? \
|
||||
demobuffer->start - demobuffer->end : \
|
||||
demobuffer->maxsize - demobuffer->end)
|
||||
//#define MIN_MVD_MEMORY 0x100000
|
||||
//#define MAXSIZE (demobuffer->end < demobuffer->last ? \
|
||||
// demobuffer->start - demobuffer->end : \
|
||||
// demobuffer->maxsize - demobuffer->end)
|
||||
|
||||
static void SV_DemoDir_Callback(struct cvar_s *var, char *oldvalue);
|
||||
|
||||
|
@ -59,10 +59,16 @@ cvar_t sv_demoSuffix = CVAR("sv_demoSuffix", "");
|
|||
cvar_t sv_demotxt = CVAR("sv_demotxt", "1");
|
||||
|
||||
void SV_WriteMVDMessage (sizebuf_t *msg, int type, int to, float time);
|
||||
void SV_WriteRecordMVDMessage (sizebuf_t *msg);
|
||||
|
||||
demo_t demo;
|
||||
static dbuffer_t *demobuffer;
|
||||
static int header = (char *)&((header_t*)0)->data - (char *)NULL;
|
||||
static float demo_prevtime;
|
||||
//static dbuffer_t *demobuffer;
|
||||
//static int header = (char *)&((header_t*)0)->data - (char *)NULL;
|
||||
static sizebuf_t demomsg;
|
||||
int demomsgtype;
|
||||
int demomsgto;
|
||||
static char demomsgbuf[MAX_OVERALLMSGLEN];
|
||||
|
||||
entity_state_t demo_entities[UPDATE_MASK+1][MAX_MVDPACKET_ENTITIES];
|
||||
client_frame_t demo_frames[UPDATE_MASK+1];
|
||||
|
@ -753,6 +759,7 @@ static void SV_DemoDir_Callback(struct cvar_s *var, char *oldvalue)
|
|||
|
||||
void SV_MVDPings (void)
|
||||
{
|
||||
sizebuf_t *msg;
|
||||
client_t *client;
|
||||
int j;
|
||||
|
||||
|
@ -761,50 +768,45 @@ void SV_MVDPings (void)
|
|||
if (client->state != cs_spawned)
|
||||
continue;
|
||||
|
||||
MVDWrite_Begin (dem_all, 0, 7);
|
||||
MSG_WriteByte(&demo.dbuf->sb, svc_updateping);
|
||||
MSG_WriteByte(&demo.dbuf->sb, j);
|
||||
MSG_WriteShort(&demo.dbuf->sb, SV_CalcPing(client, false));
|
||||
MSG_WriteByte(&demo.dbuf->sb, svc_updatepl);
|
||||
MSG_WriteByte (&demo.dbuf->sb, j);
|
||||
MSG_WriteByte (&demo.dbuf->sb, client->lossage);
|
||||
msg = MVDWrite_Begin (dem_all, 0, 7);
|
||||
MSG_WriteByte(msg, svc_updateping);
|
||||
MSG_WriteByte(msg, j);
|
||||
MSG_WriteShort(msg, SV_CalcPing(client, false));
|
||||
MSG_WriteByte(msg, svc_updatepl);
|
||||
MSG_WriteByte (msg, j);
|
||||
MSG_WriteByte (msg, client->lossage);
|
||||
}
|
||||
}
|
||||
void SV_MVD_FullClientUpdate(sizebuf_t *msg, client_t *player)
|
||||
{
|
||||
char info[MAX_INFO_STRING];
|
||||
qboolean dosizes;
|
||||
|
||||
if (!sv.mvdrecording)
|
||||
return;
|
||||
|
||||
if (msg)
|
||||
dosizes = false;
|
||||
else
|
||||
{
|
||||
dosizes = true;
|
||||
msg = &demo.dbuf->sb;
|
||||
}
|
||||
dosizes = !msg;
|
||||
|
||||
if (dosizes)
|
||||
MVDWrite_Begin (dem_all, 0, 4);
|
||||
msg = MVDWrite_Begin (dem_all, 0, 4);
|
||||
MSG_WriteByte (msg, svc_updatefrags);
|
||||
MSG_WriteByte (msg, player - svs.clients);
|
||||
MSG_WriteShort (msg, player->old_frags);
|
||||
|
||||
if (dosizes)
|
||||
MVDWrite_Begin (dem_all, 0, 4);
|
||||
msg = MVDWrite_Begin (dem_all, 0, 4);
|
||||
MSG_WriteByte (msg, svc_updateping);
|
||||
MSG_WriteByte (msg, player - svs.clients);
|
||||
MSG_WriteShort (msg, SV_CalcPing(player, false));
|
||||
|
||||
if (dosizes)
|
||||
MVDWrite_Begin (dem_all, 0, 3);
|
||||
msg = MVDWrite_Begin (dem_all, 0, 3);
|
||||
MSG_WriteByte (msg, svc_updatepl);
|
||||
MSG_WriteByte (msg, player - svs.clients);
|
||||
MSG_WriteByte (msg, player->lossage);
|
||||
|
||||
if (dosizes)
|
||||
MVDWrite_Begin (dem_all, 0, 6);
|
||||
msg = MVDWrite_Begin (dem_all, 0, 6);
|
||||
MSG_WriteByte (msg, svc_updateentertime);
|
||||
MSG_WriteByte (msg, player - svs.clients);
|
||||
MSG_WriteFloat (msg, realtime - player->connection_started);
|
||||
|
@ -815,47 +817,14 @@ void SV_MVD_FullClientUpdate(sizebuf_t *msg, client_t *player)
|
|||
Info_RemoveKey(info, "*ip");
|
||||
|
||||
if (dosizes)
|
||||
MVDWrite_Begin (dem_all, 0, 7 + strlen(info));
|
||||
msg = MVDWrite_Begin (dem_all, 0, 7 + strlen(info));
|
||||
MSG_WriteByte (msg, svc_updateuserinfo);
|
||||
MSG_WriteByte (msg, player - svs.clients);
|
||||
MSG_WriteLong (msg, player->userid);
|
||||
MSG_WriteString (msg, info);
|
||||
}
|
||||
|
||||
void MVDBuffer_Init(dbuffer_t *dbuffer, qbyte *buf, size_t size)
|
||||
{
|
||||
demobuffer = dbuffer;
|
||||
|
||||
demobuffer->data = buf;
|
||||
demobuffer->maxsize = size;
|
||||
demobuffer->start = 0;
|
||||
demobuffer->end = 0;
|
||||
demobuffer->last = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
MVD_SetMsgBuf
|
||||
|
||||
Sets the frame message buffer
|
||||
==============
|
||||
*/
|
||||
|
||||
void MVDSetMsgBuf(demobuf_t *prev,demobuf_t *cur)
|
||||
{
|
||||
// fix the maxsize of previous msg buffer,
|
||||
// we won't be able to write there anymore
|
||||
if (prev != NULL)
|
||||
prev->sb.maxsize = prev->bufsize;
|
||||
|
||||
demo.dbuf = cur;
|
||||
memset(demo.dbuf, 0, sizeof(*demo.dbuf));
|
||||
|
||||
demo.dbuf->sb.data = demobuffer->data + demobuffer->end;
|
||||
demo.dbuf->sb.maxsize = MAXSIZE;
|
||||
demo.dbuf->sb.prim = demo.recorder.netchan.netprim;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
==============
|
||||
DemoWriteToDisk
|
||||
|
@ -866,7 +835,7 @@ Message is cleared from demobuf after that
|
|||
==============
|
||||
*/
|
||||
|
||||
void SV_MVDWriteToDisk(int type, int to, float time)
|
||||
static void SV_MVDWriteToDisk(int type, int to, float time)
|
||||
{
|
||||
int pos = 0, oldm, oldd;
|
||||
header_t *p;
|
||||
|
@ -921,63 +890,21 @@ void SV_MVDWriteToDisk(int type, int to, float time)
|
|||
demobuffer->start = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
==============
|
||||
MVDSetBuf
|
||||
|
||||
Sets position in the buf for writing to specific client
|
||||
==============
|
||||
*/
|
||||
|
||||
static void MVDSetBuf(qbyte type, int to)
|
||||
sizebuf_t *MVDWrite_Begin(qbyte type, int to, int size)
|
||||
{
|
||||
header_t *p;
|
||||
int pos = 0;
|
||||
if (demomsg.cursize)
|
||||
SV_WriteMVDMessage(&demomsg, demomsgtype, demomsgto, demo_prevtime);
|
||||
|
||||
p = (header_t *)demo.dbuf->sb.data;
|
||||
demomsgtype = type;
|
||||
demomsgto = to;
|
||||
|
||||
while (pos < demo.dbuf->bufsize)
|
||||
{
|
||||
pos += header + p->size;
|
||||
|
||||
if (type == p->type && to == p->to && !p->full)
|
||||
{
|
||||
demo.dbuf->sb.cursize = pos;
|
||||
demo.dbuf->h = p;
|
||||
return;
|
||||
}
|
||||
|
||||
p = (header_t *)(p->data + p->size);
|
||||
}
|
||||
// type&&to not exist in the buf, so add it
|
||||
|
||||
p->type = type;
|
||||
p->to = to;
|
||||
p->size = 0;
|
||||
p->full = 0;
|
||||
|
||||
demo.dbuf->bufsize += header;
|
||||
demo.dbuf->sb.cursize = demo.dbuf->bufsize;
|
||||
demobuffer->end += header;
|
||||
demo.dbuf->h = p;
|
||||
}
|
||||
|
||||
void MVDMoveBuf(void)
|
||||
{
|
||||
// set the last message mark to the previous frame (i/e begining of this one)
|
||||
demobuffer->last = demobuffer->end - demo.dbuf->bufsize;
|
||||
|
||||
// move buffer to the begining of demo buffer
|
||||
memmove(demobuffer->data, demo.dbuf->sb.data, demo.dbuf->bufsize);
|
||||
demo.dbuf->sb.data = demobuffer->data;
|
||||
demobuffer->end = demo.dbuf->bufsize;
|
||||
demo.dbuf->h = NULL; // it will be setup again
|
||||
demo.dbuf->sb.maxsize = MAXSIZE + demo.dbuf->bufsize;
|
||||
}
|
||||
|
||||
qboolean MVDWrite_Begin(qbyte type, int to, int size)
|
||||
{
|
||||
demomsg.maxsize = size;
|
||||
demomsg.cursize = 0;
|
||||
demomsg.data = demomsgbuf;
|
||||
return &demomsg;
|
||||
#if 0
|
||||
qbyte *p;
|
||||
qboolean move = false;
|
||||
|
||||
|
@ -1017,28 +944,37 @@ qboolean MVDWrite_Begin(qbyte type, int to, int size)
|
|||
demobuffer->last = demobuffer->end;
|
||||
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
SV_WriteMVDMessage
|
||||
|
||||
Dumps the current net message, prefixed by the length and view angles
|
||||
Dumps the current net message, along with framing
|
||||
====================
|
||||
*/
|
||||
void SV_WriteMVDMessage (sizebuf_t *msg, int type, int to, float time)
|
||||
{
|
||||
int len, i, msec;
|
||||
qbyte c;
|
||||
static double prevtime;
|
||||
|
||||
if (!sv.mvdrecording)
|
||||
return;
|
||||
|
||||
msec = (time - prevtime)*1000;
|
||||
prevtime += msec*0.001;
|
||||
if (msec > 255) msec = 255;
|
||||
if (msec < 2) msec = 0;
|
||||
msec = (time - demo_prevtime)*1000;
|
||||
if (abs(msec) > 1000)
|
||||
{
|
||||
//catastoptic slip. debugging? reset any sync
|
||||
msec = 0;
|
||||
demo_prevtime = time;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (msec > 255) msec = 255;
|
||||
if (msec < 2) msec = 0;
|
||||
demo_prevtime += msec*0.001;
|
||||
}
|
||||
|
||||
c = msec;
|
||||
DemoWrite(&c, sizeof(c));
|
||||
|
@ -1155,8 +1091,6 @@ qboolean SV_MVDWritePackets (int num)
|
|||
nextframe = frame;
|
||||
msg.cursize = 0;
|
||||
|
||||
demo.dbuf = &frame->buf;
|
||||
|
||||
// find two frames
|
||||
// one before the exact time (time - msec) and one after,
|
||||
// then we can interpolte exact position for current frame
|
||||
|
@ -1264,8 +1198,8 @@ qboolean SV_MVDWritePackets (int num)
|
|||
demoinfo->model = cl->info.model;
|
||||
}
|
||||
|
||||
SV_MVDWriteToDisk(demo.lasttype,demo.lastto, (float)time); // this goes first to reduce demo size a bit
|
||||
SV_MVDWriteToDisk(0,0, (float)time); // now goes the rest
|
||||
//flush any intermediate data
|
||||
MVDWrite_Begin(255, -1, 0);
|
||||
if (msg.cursize)
|
||||
SV_WriteMVDMessage(&msg, dem_all, 0, (float)time);
|
||||
|
||||
|
@ -1277,9 +1211,6 @@ qboolean SV_MVDWritePackets (int num)
|
|||
if (demo.lastwritten > demo.parsecount)
|
||||
demo.lastwritten = demo.parsecount;
|
||||
|
||||
demo.dbuf = &demo.frames[demo.parsecount&DEMO_FRAMES_MASK].buf;
|
||||
demo.dbuf->sb.maxsize = MAXSIZE + demo.dbuf->bufsize;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1497,6 +1428,7 @@ stop recording a demo
|
|||
*/
|
||||
void SV_MVDStop (int reason, qboolean mvdonly)
|
||||
{
|
||||
sizebuf_t *msg;
|
||||
int numclosed;
|
||||
if (!sv.mvdrecording)
|
||||
{
|
||||
|
@ -1521,15 +1453,11 @@ void SV_MVDStop (int reason, qboolean mvdonly)
|
|||
|
||||
return;
|
||||
}
|
||||
// write a disconnect message to the demo file
|
||||
|
||||
// clearup to be sure message will fit
|
||||
demo.dbuf->sb.cursize = 0;
|
||||
demo.dbuf->h = NULL;
|
||||
demo.dbuf->bufsize = 0;
|
||||
MVDWrite_Begin(dem_all, 0, 2+strlen("EndOfDemo"));
|
||||
MSG_WriteByte (&demo.dbuf->sb, svc_disconnect);
|
||||
MSG_WriteString (&demo.dbuf->sb, "EndOfDemo");
|
||||
// write a disconnect message to the demo file
|
||||
msg = MVDWrite_Begin(dem_all, 0, 2+strlen("EndOfDemo"));
|
||||
MSG_WriteByte (msg, svc_disconnect);
|
||||
MSG_WriteString (msg, "EndOfDemo");
|
||||
|
||||
SV_MVDWritePackets(demo.parsecount - demo.lastwritten + 1);
|
||||
// finish up
|
||||
|
@ -1579,7 +1507,7 @@ Dumps the current net message, prefixed by the length and view angles
|
|||
====================
|
||||
*/
|
||||
|
||||
void SV_WriteRecordMVDMessage (sizebuf_t *msg, int seq)
|
||||
void SV_WriteRecordMVDMessage (sizebuf_t *msg)
|
||||
{
|
||||
int len;
|
||||
qbyte c;
|
||||
|
@ -1660,14 +1588,17 @@ static qboolean SV_MVD_Record (mvddest_t *dest)
|
|||
demo.recorder.frameunion.frames[i].entities.entities = demo_entities[i];
|
||||
}
|
||||
|
||||
MVDBuffer_Init(&demo.dbuffer, demo.buffer, sizeof(demo.buffer));
|
||||
MVDSetMsgBuf(NULL, &demo.frames[0].buf);
|
||||
|
||||
demo.datagram.maxsize = sizeof(demo.datagram_data);
|
||||
demo.datagram.data = demo.datagram_data;
|
||||
demo.datagram.prim = demo.recorder.netchan.netprim;
|
||||
|
||||
if (sv_demoExtensions.ival)
|
||||
if (sv_demoExtensions.ival == 2)
|
||||
{ /*more limited subset supported by ezquake*/
|
||||
demo.recorder.fteprotocolextensions = PEXT_CHUNKEDDOWNLOADS|PEXT_256PACKETENTITIES|PEXT_FLOATCOORDS|PEXT_ACCURATETIMINGS|PEXT_TRANS|PEXT_HLBSP|PEXT_MODELDBL|PEXT_ENTITYDBL|PEXT_ENTITYDBL2|PEXT_SPAWNSTATIC2;
|
||||
demo.recorder.fteprotocolextensions2 = PEXT2_VOICECHAT;
|
||||
demo.recorder.zquake_extensions = Z_EXT_PM_TYPE | Z_EXT_PM_TYPE_NEW | Z_EXT_VIEWHEIGHT | Z_EXT_SERVERTIME | Z_EXT_PITCHLIMITS | Z_EXT_JOIN_OBSERVE | Z_EXT_VWEP;
|
||||
}
|
||||
else
|
||||
{
|
||||
demo.recorder.fteprotocolextensions = PEXT_CSQC | PEXT_COLOURMOD | PEXT_DPFLAGS | PEXT_CUSTOMTEMPEFFECTS | PEXT_ENTITYDBL | PEXT_ENTITYDBL2 | PEXT_FATNESS | PEXT_HEXEN2 | PEXT_HULLSIZE | PEXT_LIGHTSTYLECOL | PEXT_MODELDBL | PEXT_SCALE | PEXT_SETATTACHMENT | PEXT_SETVIEW | PEXT_SOUNDDBL | PEXT_SPAWNSTATIC2 | PEXT_TRANS | PEXT_VIEW2;
|
||||
demo.recorder.fteprotocolextensions2 = PEXT2_VOICECHAT | PEXT2_SETANGLEDELTA | PEXT2_PRYDONCURSOR;
|
||||
|
@ -1677,6 +1608,9 @@ static qboolean SV_MVD_Record (mvddest_t *dest)
|
|||
demo.recorder.zquake_extensions = Z_EXT_PM_TYPE | Z_EXT_PM_TYPE_NEW | Z_EXT_VIEWHEIGHT | Z_EXT_SERVERTIME | Z_EXT_PITCHLIMITS | Z_EXT_JOIN_OBSERVE | Z_EXT_VWEP;
|
||||
}
|
||||
|
||||
//pointless extensions that are redundant with mvds
|
||||
demo.recorder.fteprotocolextensions &= ~PEXT_ACCURATETIMINGS | PEXT_HLBSP|PEXT_Q2BSP|PEXT_Q3BSP;
|
||||
|
||||
demo.recorder.max_net_ents = 512;
|
||||
if (demo.recorder.fteprotocolextensions & PEXT_ENTITYDBL)
|
||||
demo.recorder.max_net_ents += 512;
|
||||
|
@ -1706,7 +1640,6 @@ void SV_MVD_SendInitialGamestate(mvddest_t *dest)
|
|||
|
||||
client_t *player;
|
||||
char *gamedir;
|
||||
int seq = 1;
|
||||
|
||||
if (!demo.dest)
|
||||
return;
|
||||
|
@ -1789,7 +1722,7 @@ void SV_MVD_SendInitialGamestate(mvddest_t *dest)
|
|||
MSG_WriteString (&buf, va("fullserverinfo \"%s\"\n", svs.info) );
|
||||
|
||||
// flush packet
|
||||
SV_WriteRecordMVDMessage (&buf, seq++);
|
||||
SV_WriteRecordMVDMessage (&buf);
|
||||
SZ_Clear (&buf);
|
||||
|
||||
// soundlist
|
||||
|
@ -1805,7 +1738,7 @@ void SV_MVD_SendInitialGamestate(mvddest_t *dest)
|
|||
{
|
||||
MSG_WriteByte (&buf, 0);
|
||||
MSG_WriteByte (&buf, n);
|
||||
SV_WriteRecordMVDMessage (&buf, seq++);
|
||||
SV_WriteRecordMVDMessage (&buf);
|
||||
SZ_Clear (&buf);
|
||||
MSG_WriteByte (&buf, svc_soundlist);
|
||||
MSG_WriteByte (&buf, n + 1);
|
||||
|
@ -1818,7 +1751,7 @@ void SV_MVD_SendInitialGamestate(mvddest_t *dest)
|
|||
{
|
||||
MSG_WriteByte (&buf, 0);
|
||||
MSG_WriteByte (&buf, 0);
|
||||
SV_WriteRecordMVDMessage (&buf, seq++);
|
||||
SV_WriteRecordMVDMessage (&buf);
|
||||
SZ_Clear (&buf);
|
||||
}
|
||||
|
||||
|
@ -1835,7 +1768,7 @@ void SV_MVD_SendInitialGamestate(mvddest_t *dest)
|
|||
{
|
||||
MSG_WriteByte (&buf, 0);
|
||||
MSG_WriteByte (&buf, n);
|
||||
SV_WriteRecordMVDMessage (&buf, seq++);
|
||||
SV_WriteRecordMVDMessage (&buf);
|
||||
SZ_Clear (&buf);
|
||||
MSG_WriteByte (&buf, svc_modellist);
|
||||
MSG_WriteByte (&buf, n + 1);
|
||||
|
@ -1847,7 +1780,7 @@ void SV_MVD_SendInitialGamestate(mvddest_t *dest)
|
|||
{
|
||||
MSG_WriteByte (&buf, 0);
|
||||
MSG_WriteByte (&buf, 0);
|
||||
SV_WriteRecordMVDMessage (&buf, seq++);
|
||||
SV_WriteRecordMVDMessage (&buf);
|
||||
SZ_Clear (&buf);
|
||||
}
|
||||
|
||||
|
@ -1915,7 +1848,7 @@ void SV_MVD_SendInitialGamestate(mvddest_t *dest)
|
|||
}
|
||||
if (buf.cursize > MAX_QWMSGLEN/2)
|
||||
{
|
||||
SV_WriteRecordMVDMessage (&buf, seq++);
|
||||
SV_WriteRecordMVDMessage (&buf);
|
||||
SZ_Clear (&buf);
|
||||
}
|
||||
}
|
||||
|
@ -1927,7 +1860,7 @@ void SV_MVD_SendInitialGamestate(mvddest_t *dest)
|
|||
{
|
||||
if (buf.cursize+sv.signon_buffer_size[n] > MAX_QWMSGLEN/2)
|
||||
{
|
||||
SV_WriteRecordMVDMessage (&buf, seq++);
|
||||
SV_WriteRecordMVDMessage (&buf);
|
||||
SZ_Clear (&buf);
|
||||
}
|
||||
SZ_Write (&buf,
|
||||
|
@ -1937,7 +1870,7 @@ void SV_MVD_SendInitialGamestate(mvddest_t *dest)
|
|||
|
||||
if (buf.cursize > MAX_QWMSGLEN/2)
|
||||
{
|
||||
SV_WriteRecordMVDMessage (&buf, seq++);
|
||||
SV_WriteRecordMVDMessage (&buf);
|
||||
SZ_Clear (&buf);
|
||||
}
|
||||
|
||||
|
@ -1946,7 +1879,7 @@ void SV_MVD_SendInitialGamestate(mvddest_t *dest)
|
|||
|
||||
if (buf.cursize)
|
||||
{
|
||||
SV_WriteRecordMVDMessage (&buf, seq++);
|
||||
SV_WriteRecordMVDMessage (&buf);
|
||||
SZ_Clear (&buf);
|
||||
}
|
||||
|
||||
|
@ -1960,7 +1893,7 @@ void SV_MVD_SendInitialGamestate(mvddest_t *dest)
|
|||
|
||||
if (buf.cursize > MAX_QWMSGLEN/2)
|
||||
{
|
||||
SV_WriteRecordMVDMessage (&buf, seq++);
|
||||
SV_WriteRecordMVDMessage (&buf);
|
||||
SZ_Clear (&buf);
|
||||
}
|
||||
}
|
||||
|
@ -1993,7 +1926,7 @@ void SV_MVD_SendInitialGamestate(mvddest_t *dest)
|
|||
MSG_WriteByte (&buf, svc_stufftext);
|
||||
MSG_WriteString (&buf, "skins\n");
|
||||
|
||||
SV_WriteRecordMVDMessage (&buf, seq++);
|
||||
SV_WriteRecordMVDMessage (&buf);
|
||||
|
||||
SV_WriteSetMVDMessage();
|
||||
|
||||
|
|
|
@ -314,10 +314,10 @@ void VARGS SV_ClientPrintf (client_t *cl, int level, char *fmt, ...)
|
|||
|
||||
if (sv.mvdrecording)
|
||||
{
|
||||
MVDWrite_Begin (dem_single, cl - svs.clients, strlen(string)+3);
|
||||
MSG_WriteByte (&demo.dbuf->sb, svc_print);
|
||||
MSG_WriteByte (&demo.dbuf->sb, level);
|
||||
MSG_WriteString (&demo.dbuf->sb, string);
|
||||
sizebuf_t *msg = MVDWrite_Begin (dem_single, cl - svs.clients, strlen(string)+3);
|
||||
MSG_WriteByte (msg, svc_print);
|
||||
MSG_WriteByte (msg, level);
|
||||
MSG_WriteString (msg, string);
|
||||
}
|
||||
|
||||
if (cl->controller)
|
||||
|
@ -344,10 +344,10 @@ void VARGS SV_ClientTPrintf (client_t *cl, int level, translation_t stringnum, .
|
|||
|
||||
if (sv.mvdrecording)
|
||||
{
|
||||
MVDWrite_Begin (dem_single, cl - svs.clients, strlen(string)+3);
|
||||
MSG_WriteByte (&demo.dbuf->sb, svc_print);
|
||||
MSG_WriteByte (&demo.dbuf->sb, level);
|
||||
MSG_WriteString (&demo.dbuf->sb, string);
|
||||
sizebuf_t *msg = MVDWrite_Begin (dem_single, cl - svs.clients, strlen(string)+3);
|
||||
MSG_WriteByte (msg, svc_print);
|
||||
MSG_WriteByte (msg, level);
|
||||
MSG_WriteString (msg, string);
|
||||
}
|
||||
|
||||
SV_PrintToClient(cl, level, string);
|
||||
|
@ -393,10 +393,10 @@ void VARGS SV_BroadcastPrintf (int level, char *fmt, ...)
|
|||
|
||||
if (sv.mvdrecording)
|
||||
{
|
||||
MVDWrite_Begin (dem_all, 0, strlen(string)+3);
|
||||
MSG_WriteByte (&demo.dbuf->sb, svc_print);
|
||||
MSG_WriteByte (&demo.dbuf->sb, level);
|
||||
MSG_WriteString (&demo.dbuf->sb, string);
|
||||
sizebuf_t *msg = MVDWrite_Begin (dem_all, 0, strlen(string)+3);
|
||||
MSG_WriteByte (msg, svc_print);
|
||||
MSG_WriteByte (msg, level);
|
||||
MSG_WriteString (msg, string);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -794,24 +794,24 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int
|
|||
}
|
||||
}
|
||||
|
||||
if (sv.mvdrecording && !with) //mvds don't get the pext stuff
|
||||
if (sv.mvdrecording && ((demo.recorder.fteprotocolextensions & with) == with) && !(demo.recorder.fteprotocolextensions & without))
|
||||
{
|
||||
sizebuf_t *msg;
|
||||
if (!mask)
|
||||
{
|
||||
/*no distinction between reliable or not*/
|
||||
MVDWrite_Begin(dem_single, pnum, sv.multicast.cursize);
|
||||
SZ_Write(&demo.dbuf->sb, sv.multicast.data, sv.multicast.cursize);
|
||||
msg = MVDWrite_Begin(dem_single, pnum, sv.multicast.cursize);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (reliable)
|
||||
{
|
||||
MVDWrite_Begin(dem_all, 0, sv.multicast.cursize);
|
||||
SZ_Write(&demo.dbuf->sb, sv.multicast.data, sv.multicast.cursize);
|
||||
msg = MVDWrite_Begin(dem_all, 0, sv.multicast.cursize);
|
||||
}
|
||||
else
|
||||
SZ_Write(&demo.datagram, sv.multicast.data, sv.multicast.cursize);
|
||||
msg = &demo.datagram;
|
||||
}
|
||||
SZ_Write(&demo.datagram, sv.multicast.data, sv.multicast.cursize);
|
||||
}
|
||||
|
||||
#ifdef NQPROT
|
||||
|
@ -1141,9 +1141,9 @@ void SV_WriteCenterPrint(client_t *cl, char *s)
|
|||
|
||||
if (sv.mvdrecording)
|
||||
{
|
||||
MVDWrite_Begin (dem_single, cl - svs.clients, 2 + strlen(s));
|
||||
MSG_WriteByte (&demo.dbuf->sb, svc_centerprint);
|
||||
MSG_WriteString (&demo.dbuf->sb, s);
|
||||
sizebuf_t *msg = MVDWrite_Begin (dem_single, cl - svs.clients, 2 + strlen(s));
|
||||
MSG_WriteByte (msg, svc_centerprint);
|
||||
MSG_WriteString (msg, s);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2025,10 +2025,10 @@ void SV_UpdateToReliableMessages (void)
|
|||
|
||||
if (sv.mvdrecording)
|
||||
{
|
||||
MVDWrite_Begin(dem_all, 0, 4);
|
||||
MSG_WriteByte(&demo.dbuf->sb, svc_updatefrags);
|
||||
MSG_WriteByte(&demo.dbuf->sb, i);
|
||||
MSG_WriteShort(&demo.dbuf->sb, host_client->edict->v->frags);
|
||||
sizebuf_t *msg = MVDWrite_Begin(dem_all, 0, 4);
|
||||
MSG_WriteByte(msg, svc_updatefrags);
|
||||
MSG_WriteByte(msg, i);
|
||||
MSG_WriteShort(msg, host_client->edict->v->frags);
|
||||
}
|
||||
|
||||
host_client->old_frags = host_client->edict->v->frags;
|
||||
|
@ -2086,10 +2086,10 @@ void SV_UpdateToReliableMessages (void)
|
|||
|
||||
if (sv.mvdrecording)
|
||||
{
|
||||
MVDWrite_Begin(dem_all, 0, 4);
|
||||
MSG_WriteByte(&demo.dbuf->sb, svc_updatefrags);
|
||||
MSG_WriteByte(&demo.dbuf->sb, i);
|
||||
MSG_WriteShort(&demo.dbuf->sb, curfrags);
|
||||
sizebuf_t *msg = MVDWrite_Begin(dem_all, 0, 4);
|
||||
MSG_WriteByte(msg, svc_updatefrags);
|
||||
MSG_WriteByte(msg, i);
|
||||
MSG_WriteShort(msg, curfrags);
|
||||
}
|
||||
|
||||
host_client->old_frags = curfrags;
|
||||
|
@ -2391,6 +2391,7 @@ void SV_SendMVDMessage(void)
|
|||
extern cvar_t sv_demofps;
|
||||
extern cvar_t sv_demoPings;
|
||||
// extern cvar_t sv_demoMaxSize;
|
||||
sizebuf_t *dmsg;
|
||||
|
||||
SV_MVD_RunPendingConnections();
|
||||
|
||||
|
@ -2461,11 +2462,11 @@ void SV_SendMVDMessage(void)
|
|||
if (statss[j] || demo.statss[i][j])
|
||||
if (strcmp(statss[j]?statss[j]:"", demo.statss[i][j]?demo.statss[i][j]:""))
|
||||
{
|
||||
MVDWrite_Begin(dem_stats, i, 3+strlen(statss[j]));
|
||||
sizebuf_t *msg = MVDWrite_Begin(dem_stats, i, 3+strlen(statss[j]));
|
||||
demo.statss[i][j] = statss[j];
|
||||
MSG_WriteByte(&demo.dbuf->sb, svcfte_updatestatstring);
|
||||
MSG_WriteByte(&demo.dbuf->sb, j);
|
||||
MSG_WriteString(&demo.dbuf->sb, statss[j]);
|
||||
MSG_WriteByte(msg, svcfte_updatestatstring);
|
||||
MSG_WriteByte(msg, j);
|
||||
MSG_WriteString(msg, statss[j]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2477,17 +2478,17 @@ void SV_SendMVDMessage(void)
|
|||
{
|
||||
if (statsf[j] - (float)(int)statsf[j] == 0 && statsf[j] >= 0 && statsf[j] <= 255)
|
||||
{
|
||||
MVDWrite_Begin(dem_stats, i, 3);
|
||||
MSG_WriteByte(&demo.dbuf->sb, svc_updatestat);
|
||||
MSG_WriteByte(&demo.dbuf->sb, j);
|
||||
MSG_WriteByte(&demo.dbuf->sb, statsf[j]);
|
||||
dmsg = MVDWrite_Begin(dem_stats, i, 3);
|
||||
MSG_WriteByte(dmsg, svc_updatestat);
|
||||
MSG_WriteByte(dmsg, j);
|
||||
MSG_WriteByte(dmsg, statsf[j]);
|
||||
}
|
||||
else
|
||||
{
|
||||
MVDWrite_Begin(dem_stats, i, 6);
|
||||
MSG_WriteByte(&demo.dbuf->sb, svcfte_updatestatfloat);
|
||||
MSG_WriteByte(&demo.dbuf->sb, j);
|
||||
MSG_WriteFloat(&demo.dbuf->sb, statsf[j]);
|
||||
dmsg = MVDWrite_Begin(dem_stats, i, 6);
|
||||
MSG_WriteByte(dmsg, svcfte_updatestatfloat);
|
||||
MSG_WriteByte(dmsg, j);
|
||||
MSG_WriteFloat(dmsg, statsf[j]);
|
||||
}
|
||||
demo.statsf[i][j] = statsf[j];
|
||||
/*make sure statsf is correct*/
|
||||
|
@ -2505,17 +2506,17 @@ void SV_SendMVDMessage(void)
|
|||
demo.statsf[i][j] = statsi[j];
|
||||
if (statsi[j] >=0 && statsi[j] <= 255)
|
||||
{
|
||||
MVDWrite_Begin(dem_stats, i, 3);
|
||||
MSG_WriteByte(&demo.dbuf->sb, svc_updatestat);
|
||||
MSG_WriteByte(&demo.dbuf->sb, j);
|
||||
MSG_WriteByte(&demo.dbuf->sb, statsi[j]);
|
||||
dmsg = MVDWrite_Begin(dem_stats, i, 3);
|
||||
MSG_WriteByte(dmsg, svc_updatestat);
|
||||
MSG_WriteByte(dmsg, j);
|
||||
MSG_WriteByte(dmsg, statsi[j]);
|
||||
}
|
||||
else
|
||||
{
|
||||
MVDWrite_Begin(dem_stats, i, 6);
|
||||
MSG_WriteByte(&demo.dbuf->sb, svc_updatestatlong);
|
||||
MSG_WriteByte(&demo.dbuf->sb, j);
|
||||
MSG_WriteLong(&demo.dbuf->sb, statsi[j]);
|
||||
dmsg = MVDWrite_Begin(dem_stats, i, 6);
|
||||
MSG_WriteByte(dmsg, svc_updatestatlong);
|
||||
MSG_WriteByte(dmsg, j);
|
||||
MSG_WriteLong(dmsg, statsi[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2531,15 +2532,14 @@ void SV_SendMVDMessage(void)
|
|||
|
||||
SV_WriteEntitiesToClient (&demo.recorder, &msg, true);
|
||||
|
||||
if (!MVDWrite_Begin(dem_all, 0, msg.cursize))
|
||||
return;
|
||||
|
||||
SZ_Write (&demo.dbuf->sb, msg.data, msg.cursize);
|
||||
dmsg = MVDWrite_Begin(dem_all, 0, msg.cursize);
|
||||
SZ_Write (dmsg, msg.data, msg.cursize);
|
||||
// copy the accumulated multicast datagram
|
||||
// for this client out to the message
|
||||
if (demo.datagram.cursize) {
|
||||
MVDWrite_Begin(dem_all, 0, demo.datagram.cursize);
|
||||
SZ_Write (&demo.dbuf->sb, demo.datagram.data, demo.datagram.cursize);
|
||||
if (demo.datagram.cursize)
|
||||
{
|
||||
dmsg = MVDWrite_Begin(dem_all, 0, demo.datagram.cursize);
|
||||
SZ_Write (dmsg, demo.datagram.data, demo.datagram.cursize);
|
||||
SZ_Clear (&demo.datagram);
|
||||
}
|
||||
|
||||
|
@ -2553,7 +2553,7 @@ void SV_SendMVDMessage(void)
|
|||
}
|
||||
|
||||
demo.parsecount++;
|
||||
MVDSetMsgBuf(demo.dbuf,&demo.frames[demo.parsecount&DEMO_FRAMES_MASK].buf);
|
||||
// MVDSetMsgBuf(demo.dbuf,&demo.frames[demo.parsecount&DEMO_FRAMES_MASK].buf);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2351,10 +2351,11 @@ void SV_VoiceReadPacket(void)
|
|||
|
||||
if (sv.mvdrecording && sv_voip_record.ival && !(sv_voip_record.ival == 2 && !host_client->spectator))
|
||||
{
|
||||
sizebuf_t *msg;
|
||||
// non-team messages should be seen always, even if not tracking any player
|
||||
if (vt == VT_ALL && (!host_client->spectator || sv_spectalk.ival))
|
||||
{
|
||||
MVDWrite_Begin (dem_all, 0, ring->datalen+6);
|
||||
msg = MVDWrite_Begin (dem_all, 0, ring->datalen+6);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2363,15 +2364,15 @@ void SV_VoiceReadPacket(void)
|
|||
(ring->receiver[1]<<8) |
|
||||
(ring->receiver[2]<<16) |
|
||||
(ring->receiver[3]<<24);
|
||||
MVDWrite_Begin (dem_multiple, cls, ring->datalen+6);
|
||||
msg = MVDWrite_Begin (dem_multiple, cls, ring->datalen+6);
|
||||
}
|
||||
|
||||
MSG_WriteByte( &demo.dbuf->sb, svcfte_voicechat);
|
||||
MSG_WriteByte( &demo.dbuf->sb, ring->sender);
|
||||
MSG_WriteByte( &demo.dbuf->sb, ring->gen);
|
||||
MSG_WriteByte( &demo.dbuf->sb, ring->seq);
|
||||
MSG_WriteShort(&demo.dbuf->sb, ring->datalen);
|
||||
SZ_Write( &demo.dbuf->sb, ring->data, ring->datalen);
|
||||
MSG_WriteByte(msg, svcfte_voicechat);
|
||||
MSG_WriteByte(msg, ring->sender);
|
||||
MSG_WriteByte(msg, ring->gen);
|
||||
MSG_WriteByte(msg, ring->seq);
|
||||
MSG_WriteShort(msg, ring->datalen);
|
||||
SZ_Write(msg, ring->data, ring->datalen);
|
||||
}
|
||||
}
|
||||
void SV_VoiceInitClient(client_t *client)
|
||||
|
@ -3088,6 +3089,7 @@ void SV_Say (qboolean team)
|
|||
char t1[32], *t2;
|
||||
int cls = 0;
|
||||
float floodtime;
|
||||
sizebuf_t *msg;
|
||||
|
||||
qboolean sent[MAX_CLIENTS]; //so we don't send to the same splitscreen connection twice. (it's ugly)
|
||||
int cln;
|
||||
|
@ -3222,15 +3224,13 @@ void SV_Say (qboolean team)
|
|||
|
||||
// non-team messages should be seen always, even if not tracking any player
|
||||
if (!team && ((host_client->spectator && sv_spectalk.value) || !host_client->spectator))
|
||||
{
|
||||
MVDWrite_Begin (dem_all, 0, strlen(text)+3);
|
||||
}
|
||||
msg = MVDWrite_Begin (dem_all, 0, strlen(text)+3);
|
||||
else
|
||||
MVDWrite_Begin (dem_multiple, cls, strlen(text)+3);
|
||||
msg = MVDWrite_Begin (dem_multiple, cls, strlen(text)+3);
|
||||
|
||||
MSG_WriteByte (&demo.dbuf->sb, svc_print);
|
||||
MSG_WriteByte (&demo.dbuf->sb, PRINT_CHAT);
|
||||
MSG_WriteString (&demo.dbuf->sb, text);
|
||||
MSG_WriteByte (msg, svc_print);
|
||||
MSG_WriteByte (msg, PRINT_CHAT);
|
||||
MSG_WriteString (msg, text);
|
||||
}
|
||||
|
||||
|
||||
|
@ -3664,11 +3664,11 @@ void SV_SetInfo_f (void)
|
|||
|
||||
if (sv.mvdrecording)
|
||||
{
|
||||
MVDWrite_Begin (dem_all, 0, strlen(key)+strlen(val)+4);
|
||||
MSG_WriteByte (&demo.dbuf->sb, svc_setinfo);
|
||||
MSG_WriteByte (&demo.dbuf->sb, i);
|
||||
MSG_WriteString (&demo.dbuf->sb, key);
|
||||
MSG_WriteString (&demo.dbuf->sb, val);
|
||||
sizebuf_t *msg = MVDWrite_Begin (dem_all, 0, strlen(key)+strlen(val)+4);
|
||||
MSG_WriteByte (msg, svc_setinfo);
|
||||
MSG_WriteByte (msg, i);
|
||||
MSG_WriteString (msg, key);
|
||||
MSG_WriteString (msg, val);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,13 @@
|
|||
//s0=diffuse, s1=normal, s2=specular, s3=shadowmap
|
||||
//custom modifiers:
|
||||
//PCF(shadowmap)
|
||||
//CUBE(projected cubemap)
|
||||
//CUBEPROJ(projected cubemap)
|
||||
//SPOT(projected circle
|
||||
//CUBESHADOW
|
||||
|
||||
#if 0 && defined(GL_ARB_texture_gather) && defined(PCF)
|
||||
#extension GL_ARB_texture_gather : enable
|
||||
#endif
|
||||
|
||||
|
||||
varying vec2 tcbase;
|
||||
|
@ -19,10 +25,13 @@ varying vec3 lightvector;
|
|||
#if defined(SPECULAR) || defined(OFFSETMAPPING)
|
||||
varying vec3 eyevector;
|
||||
#endif
|
||||
#if defined(PCF) || defined(CUBE)
|
||||
varying vec4 vshadowcoord;
|
||||
#if defined(PCF) || defined(CUBEPROJ)
|
||||
varying vec4 vtexprojcoord;
|
||||
uniform mat4 l_cubematrix;
|
||||
#ifndef SPOT
|
||||
uniform mat4 l_projmatrix;
|
||||
#endif
|
||||
#endif
|
||||
#ifdef VERTEX_SHADER
|
||||
#include "sys/skeletal.h"
|
||||
uniform vec3 l_lightposition;
|
||||
|
@ -45,33 +54,142 @@ void main ()
|
|||
eyevector.y = dot(eyeminusvertex, t.xyz);
|
||||
eyevector.z = dot(eyeminusvertex, n.xyz);
|
||||
#endif
|
||||
#if defined(PCF) || defined(SPOT) || defined(PROJECTION) || defined(CUBE)
|
||||
vshadowcoord = l_projmatrix*vec4(w.xyz, 1.0);
|
||||
#if defined(PCF) || defined(SPOT) || defined(PROJECTION)
|
||||
//for texture projections/shadowmapping on dlights
|
||||
vtexprojcoord = (l_cubematrix*vec4(w.xyz, 1.0));
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef FRAGMENT_SHADER
|
||||
#include "sys/fog.h"
|
||||
uniform sampler2D s_t0;
|
||||
|
||||
#if defined(BUMP) || defined(SPECULAR) || defined(OFFSETMAPPING)
|
||||
uniform sampler2D s_t1;
|
||||
#endif
|
||||
#ifdef SPECULAR
|
||||
uniform sampler2D s_t2;
|
||||
#endif
|
||||
#ifdef CUBE
|
||||
#ifdef CUBEPROJ
|
||||
uniform samplerCube s_t3;
|
||||
#endif
|
||||
#ifdef PCF
|
||||
#ifdef CUBE
|
||||
uniform samplerCubeShadow s_t7;
|
||||
#ifdef CUBESHADOW
|
||||
uniform samplerCubeShadow s_t4;
|
||||
#else
|
||||
uniform sampler2DShadow s_t7;
|
||||
#if 0//def GL_ARB_texture_gather
|
||||
uniform sampler2D s_t4;
|
||||
#else
|
||||
uniform sampler2DShadow s_t4;
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
uniform float l_lightradius;
|
||||
uniform vec3 l_lightcolour;
|
||||
uniform vec3 l_lightcolourscale;
|
||||
|
||||
|
||||
|
||||
#ifdef PCF
|
||||
//#define shadow2DProj(t,c) (vec2(1.0,1.0))
|
||||
//#define shadow2DProj(t,c) texture2DProj(t,c).rg
|
||||
|
||||
float ShadowmapFilter(void)
|
||||
{
|
||||
#ifdef SPOT
|
||||
const vec3 texscale = vec3(1.0/512.0, 1.0/512.0, 1.0);
|
||||
#else
|
||||
const vec3 texscale = vec3(1.0/(512.0*3.0), 1.0/(512.0*2.0), 1.0);
|
||||
#endif
|
||||
|
||||
//dehomogonize input
|
||||
vec3 shadowcoord = (vtexprojcoord.xyz / vtexprojcoord.w);
|
||||
|
||||
#ifdef CUBESHADOW
|
||||
// vec3 shadowcoord = vshadowcoord.xyz / vshadowcoord.w;
|
||||
// #define dosamp(x,y) shadowCube(s_t4, shadowcoord + vec2(x,y)*texscale.xy).r
|
||||
#else
|
||||
|
||||
#ifdef SPOT
|
||||
//bias it. don't bother figuring out which side or anything, its not needed
|
||||
//l_projmatrix contains the light's projection matrix so no other magic needed
|
||||
shadowcoord.xyz = (shadowcoord.xyz + vec3(1.0, 1.0, 1.0)) * vec3(0.5, 0.5, 0.5);
|
||||
#else
|
||||
//figure out which axis to use
|
||||
//texture is arranged thusly:
|
||||
//forward left up
|
||||
//back right down
|
||||
vec3 dir = abs(shadowcoord);
|
||||
//assume z is the major axis (ie: forward from the light)
|
||||
vec3 t = shadowcoord;
|
||||
float ma = dir.z;
|
||||
vec4 axis = vec4(1.0, 1.0, 1.0, 0.0);
|
||||
if (dir.x > ma)
|
||||
{
|
||||
ma = dir.x;
|
||||
t = shadowcoord.zyx;
|
||||
axis.x = 3.0;
|
||||
}
|
||||
if (dir.y > ma)
|
||||
{
|
||||
ma = dir.y;
|
||||
t = shadowcoord.xzy;
|
||||
axis.x = 5.0;
|
||||
}
|
||||
if (t.z > 0.0)
|
||||
{
|
||||
axis.y = 3.0;
|
||||
t.z = -t.z;
|
||||
}
|
||||
|
||||
|
||||
//we also need to pass the result through the light's projection matrix too
|
||||
vec4 nsc =l_projmatrix*vec4(t, 1.0);
|
||||
shadowcoord = (nsc.xyz / nsc.w);
|
||||
|
||||
//now bias and relocate it
|
||||
shadowcoord = (shadowcoord + axis.xyz) * vec3(0.5/3.0, 0.5/2.0, 0.5);
|
||||
#endif
|
||||
|
||||
#if 0//def GL_ARB_texture_gather
|
||||
vec2 ipart, fpart;
|
||||
#define dosamp(x,y) textureGatherOffset(s_t4, ipart.xy, vec2(x,y)))
|
||||
vec4 tl = step(shadowcoord.z, dosamp(-1.0, -1.0));
|
||||
vec4 bl = step(shadowcoord.z, dosamp(-1.0, 1.0));
|
||||
vec4 tr = step(shadowcoord.z, dosamp(1.0, -1.0));
|
||||
vec4 br = step(shadowcoord.z, dosamp(1.0, 1.0));
|
||||
//we now have 4*4 results, woo
|
||||
//we can just average them for 1/16th precision, but that's still limited graduations
|
||||
//the middle four pixels are 'full strength', but we interpolate the sides to effectively give 3*3
|
||||
vec4 col = vec4(tl.ba, tr.ba) + vec4(bl.rg, br.rg) + //middle two rows are full strength
|
||||
mix(vec4(tl.rg, tr.rg), vec4(bl.ba, br.ba), fpart.y); //top+bottom rows
|
||||
return dot(mix(col.rgb, col.agb, fpart.x), vec3(1.0/9.0)); //blend r+a, gb are mixed because its pretty much free and gives a nicer dot instruction instead of lots of adds.
|
||||
|
||||
#else
|
||||
#define dosamp(x,y) shadow2D(s_t4, shadowcoord.xyz + (vec3(x,y,0.0)*texscale.xyz)).r
|
||||
float s = 0.0;
|
||||
s += dosamp(-1.0, -1.0);
|
||||
s += dosamp(-1.0, 0.0);
|
||||
s += dosamp(-1.0, 1.0);
|
||||
s += dosamp(0.0, -1.0);
|
||||
s += dosamp(0.0, 0.0);
|
||||
s += dosamp(0.0, 1.0);
|
||||
s += dosamp(1.0, -1.0);
|
||||
s += dosamp(1.0, 0.0);
|
||||
s += dosamp(1.0, 1.0);
|
||||
return s/9.0;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef OFFSETMAPPING
|
||||
#include "sys/offsetmapping.h"
|
||||
#endif
|
||||
|
@ -96,6 +214,7 @@ void main ()
|
|||
#ifdef BUMP
|
||||
diff = bases * (l_lightcolourscale.x + l_lightcolourscale.y * max(dot(bumps, nl), 0.0));
|
||||
#else
|
||||
//we still do bumpmapping even without bumps to ensure colours are always sane. light.exe does it too.
|
||||
diff = bases * (l_lightcolourscale.x + l_lightcolourscale.y * max(dot(vec3(0.0, 0.0, 1.0), nl), 0.0));
|
||||
#endif
|
||||
|
||||
|
@ -108,54 +227,30 @@ void main ()
|
|||
|
||||
|
||||
|
||||
#ifdef CUBE
|
||||
diff *= textureCube(s_t3, vshadowcoord.xyz).rgb;
|
||||
#endif
|
||||
#ifdef PCF
|
||||
#if defined(SPOT)
|
||||
const float texx = 512.0;
|
||||
const float texy = 512.0;
|
||||
vec4 shadowcoord = vshadowcoord;
|
||||
#else
|
||||
const float texx = 512.0;
|
||||
const float texy = 512.0;
|
||||
vec4 shadowcoord;
|
||||
shadowcoord.zw = vshadowcoord.zw;
|
||||
shadowcoord.xy = vshadowcoord.xy;
|
||||
#endif
|
||||
#ifdef CUBE
|
||||
const float xPixelOffset = 1.0/texx; const float yPixelOffset = 1.0/texy; float s = 0.0;
|
||||
s += shadowCubeProj(s_t7, shadowcoord + vec4(-1.0 * xPixelOffset * shadowcoord.w, -1.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;
|
||||
s += shadowCubeProj(s_t7, shadowcoord + vec4(-1.0 * xPixelOffset * shadowcoord.w, 0.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;
|
||||
s += shadowCubeProj(s_t7, shadowcoord + vec4(-1.0 * xPixelOffset * shadowcoord.w, 1.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;
|
||||
s += shadowCubeProj(s_t7, shadowcoord + vec4(0.0 * xPixelOffset * shadowcoord.w, -1.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;
|
||||
s += shadowCubeProj(s_t7, shadowcoord + vec4(0.0 * xPixelOffset * shadowcoord.w, 0.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;
|
||||
s += shadowCubeProj(s_t7, shadowcoord + vec4(0.0 * xPixelOffset * shadowcoord.w, 1.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;
|
||||
s += shadowCubeProj(s_t7, shadowcoord + vec4(1.0 * xPixelOffset * shadowcoord.w, -1.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;
|
||||
s += shadowCubeProj(s_t7, shadowcoord + vec4(1.0 * xPixelOffset * shadowcoord.w, 0.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;
|
||||
s += shadowCubeProj(s_t7, shadowcoord + vec4(1.0 * xPixelOffset * shadowcoord.w, 1.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;
|
||||
colorscale *= s/9.0;
|
||||
#else
|
||||
const float xPixelOffset = 1.0/texx; const float yPixelOffset = 1.0/texy; float s = 0.0;
|
||||
s += shadow2DProj(s_t7, shadowcoord + vec4(-1.0 * xPixelOffset * shadowcoord.w, -1.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;
|
||||
s += shadow2DProj(s_t7, shadowcoord + vec4(-1.0 * xPixelOffset * shadowcoord.w, 0.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;
|
||||
s += shadow2DProj(s_t7, shadowcoord + vec4(-1.0 * xPixelOffset * shadowcoord.w, 1.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;
|
||||
s += shadow2DProj(s_t7, shadowcoord + vec4(0.0 * xPixelOffset * shadowcoord.w, -1.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;
|
||||
s += shadow2DProj(s_t7, shadowcoord + vec4(0.0 * xPixelOffset * shadowcoord.w, 0.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;
|
||||
s += shadow2DProj(s_t7, shadowcoord + vec4(0.0 * xPixelOffset * shadowcoord.w, 1.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;
|
||||
s += shadow2DProj(s_t7, shadowcoord + vec4(1.0 * xPixelOffset * shadowcoord.w, -1.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;
|
||||
s += shadow2DProj(s_t7, shadowcoord + vec4(1.0 * xPixelOffset * shadowcoord.w, 0.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;
|
||||
s += shadow2DProj(s_t7, shadowcoord + vec4(1.0 * xPixelOffset * shadowcoord.w, 1.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;
|
||||
colorscale *= s/9.0;
|
||||
#endif
|
||||
#ifdef CUBEPROJ
|
||||
/*filter the colour by the cubemap projection*/
|
||||
diff *= textureCube(s_t3, vtexprojcoord.xyz).rgb;
|
||||
#endif
|
||||
|
||||
#if defined(SPOT)
|
||||
if (shadowcoord.w < 0.0) discard;
|
||||
vec2 spot = ((shadowcoord.st)/shadowcoord.w - 0.5)*2.0;colorscale*=1.0-(dot(spot,spot));
|
||||
/*filter the colour by the spotlight. discard anything behind the light so we don't get a mirror image*/
|
||||
if (vtexprojcoord.w < 0.0) discard;
|
||||
vec2 spot = ((vtexprojcoord.st)/vtexprojcoord.w);colorscale*=1.0-(dot(spot,spot));
|
||||
#endif
|
||||
|
||||
#ifdef PCF
|
||||
/*filter the light by the shadowmap. logically a boolean, but we allow fractions for softer shadows*/
|
||||
//diff.rgb = (vtexprojcoord.xyz/vtexprojcoord.w) * 0.5 + 0.5;
|
||||
colorscale *= ShadowmapFilter();
|
||||
// gl_FragColor.rgb = vec3(ShadowmapFilter());
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(PROJECTION)
|
||||
l_lightcolour *= texture2d(s_t3, shadowcoord);
|
||||
/*2d projection, not used*/
|
||||
// diff *= texture2d(s_t3, shadowcoord);
|
||||
#endif
|
||||
|
||||
gl_FragColor.rgb = fog3additive(diff*colorscale*l_lightcolour);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -2,14 +2,17 @@
|
|||
#include "sys/fog.h"
|
||||
varying vec2 tc;
|
||||
varying vec2 lm;
|
||||
varying vec4 vc;
|
||||
|
||||
#ifdef VERTEX_SHADER
|
||||
attribute vec2 v_texcoord;
|
||||
attribute vec2 v_lmcoord;
|
||||
attribute vec4 v_colour;
|
||||
void main (void)
|
||||
{
|
||||
tc = v_texcoord.st;
|
||||
lm = v_lmcoord.st;
|
||||
vc = v_colour;
|
||||
gl_Position = ftetransform();
|
||||
}
|
||||
#endif
|
||||
|
@ -32,7 +35,7 @@ void main (void)
|
|||
{
|
||||
vec4 m = texture2D(s_t4, lm);
|
||||
|
||||
gl_FragColor = fog4(vec4(m.aaa,1.0)*(
|
||||
gl_FragColor = fog4(vc*vec4(m.aaa,1.0)*(
|
||||
texture2D(s_t0, tc)*m.r
|
||||
+ texture2D(s_t1, tc)*m.g
|
||||
+ texture2D(s_t2, tc)*m.b
|
||||
|
|
Loading…
Reference in a new issue