preliminary attempt to get rtlights in d3d builds. shadows are only cast by world, and the hlsl code is somewhat lacking. also only works in d3d-only builds.
no longer using the vfw header or lib, so avi playback/recording should work when compiled with gcc. added d_mipcap cvar. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@3944 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
ebc29fe683
commit
d877bd4e39
20 changed files with 1491 additions and 906 deletions
|
@ -118,7 +118,7 @@ static void CL_ClearDlight(dlight_t *dl, int key)
|
|||
dl->color[0] = 1;
|
||||
dl->color[1] = 1;
|
||||
dl->color[2] = 1;
|
||||
dl->corona = r_flashblend.value;
|
||||
dl->corona = r_flashblend.value * 0.25;
|
||||
dl->coronascale = r_flashblendscale.value;
|
||||
// if (r_shadow_realtime_dlight_shadowmap.value)
|
||||
// dl->flags |= LFLAG_SHADOWMAP;
|
||||
|
@ -2057,7 +2057,7 @@ void CL_LinkPacketEntities (void)
|
|||
if (state->effects & EF_RED)
|
||||
{
|
||||
radius = max(radius,200);
|
||||
colour[0] += 5.0;
|
||||
colour[0] += 3.0;
|
||||
colour[1] += 0.5;
|
||||
colour[2] += 0.5;
|
||||
}
|
||||
|
@ -2081,8 +2081,20 @@ void CL_LinkPacketEntities (void)
|
|||
colour[1] = state->light[1]/1024.0f;
|
||||
colour[2] = state->light[2]/1024.0f;
|
||||
}
|
||||
CL_NewDlight(state->number, state->origin, state->light[3]?state->light[3]:350, 0.1, colour[0], colour[1], colour[2]);
|
||||
/*FIXME: .skin is meant to be "cubemaps/%i" */
|
||||
dl = CL_NewDlight(state->number, state->origin, state->light[3]?state->light[3]:350, 0.1, colour[0], colour[1], colour[2]);
|
||||
dl->corona = (state->lightpflags & PFLAGS_CORONA)?1:0;
|
||||
dl->coronascale = 0.25;
|
||||
dl->flags &= ~LFLAG_FLASHBLEND;
|
||||
dl->flags |= (state->lightpflags & PFLAGS_NOSHADOW)?LFLAG_NOSHADOWS:0;
|
||||
if (state->skinnum)
|
||||
{
|
||||
VectorCopy(angles, ent->angles);
|
||||
angles[0]*=-1; //pflags matches alias models.
|
||||
AngleVectors(angles, dl->axis[0], dl->axis[1], dl->axis[2]);
|
||||
VectorInverse(dl->axis[1]);
|
||||
snprintf(dl->cubemapname, sizeof(dl->cubemapname), "cubemaps/%i", state->skinnum);
|
||||
dl->cubetexture = R_LoadReplacementTexture(dl->cubemapname, "", IF_CUBEMAP);
|
||||
}
|
||||
}
|
||||
|
||||
// if set to invisible, skip
|
||||
|
@ -2149,31 +2161,6 @@ void CL_LinkPacketEntities (void)
|
|||
ent->drawflags = state->hexen2flags;
|
||||
|
||||
CL_LerpNetFrameState(FS_REG, &ent->framestate, le);
|
||||
/*
|
||||
// set frame
|
||||
if (le->framechange == le->oldframechange)
|
||||
ent->framestate.g[FS_REG].lerpfrac = 0;
|
||||
else
|
||||
{
|
||||
ent->framestate.g[FS_REG].lerpfrac = 1-(servertime - le->framechange) / (le->framechange - le->oldframechange);
|
||||
if (ent->framestate.g[FS_REG].lerpfrac > 1)
|
||||
ent->framestate.g[FS_REG].lerpfrac = 1;
|
||||
else if (ent->framestate.g[FS_REG].lerpfrac < 0)
|
||||
{
|
||||
ent->framestate.g[FS_REG].lerpfrac = 0;
|
||||
//le->oldframechange = le->framechange;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ent->framestate.g[FS_REG].frame[0] = state->frame;
|
||||
ent->framestate.g[FS_REG].frame[1] = le->frame;
|
||||
|
||||
ent->framestate.g[FS_REG].frametime[0] = cl.servertime - le->framechange;
|
||||
ent->framestate.g[FS_REG].frametime[1] = cl.servertime - le->oldframechange;
|
||||
*/
|
||||
|
||||
// f = (sin(realtime)+1)/2;
|
||||
|
||||
#ifdef PEXT_SCALE
|
||||
//set scale
|
||||
|
@ -2269,9 +2256,9 @@ void CL_LinkPacketEntities (void)
|
|||
float rad = 0;
|
||||
vec3_t dclr;
|
||||
|
||||
dclr[0] = 0.20;
|
||||
dclr[1] = 0.10;
|
||||
dclr[2] = 0;
|
||||
dclr[0] = 2.0;
|
||||
dclr[1] = 1.0;
|
||||
dclr[2] = 0.25;
|
||||
|
||||
if (model->flags & MF_ROCKET)
|
||||
{
|
||||
|
@ -2281,7 +2268,6 @@ void CL_LinkPacketEntities (void)
|
|||
if (strncmp(model->name, "models/sflesh", 13))
|
||||
{ //hmm. hexen spider gibs...
|
||||
rad = 200;
|
||||
dclr[2] = 0.05;
|
||||
rad += r_lightflicker.value?((flicker + state->number)&31):0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1077,9 +1077,9 @@ void CL_ParseTEnt (void)
|
|||
dl->die = cl.time + 1;
|
||||
dl->decay = 300;
|
||||
|
||||
dl->color[0] = 1.0;
|
||||
dl->color[1] = 0.775;
|
||||
dl->color[2] = 0.25;
|
||||
dl->color[0] = 4.0;
|
||||
dl->color[1] = 2.0;
|
||||
dl->color[2] = 0.5;
|
||||
dl->channelfade[0] = 0.196;
|
||||
dl->channelfade[1] = 0.23;
|
||||
dl->channelfade[2] = 0.12;
|
||||
|
@ -1117,12 +1117,12 @@ void CL_ParseTEnt (void)
|
|||
dl->die = cl.time + 1;
|
||||
dl->decay = 300;
|
||||
|
||||
dl->color[0] = 1.0;
|
||||
dl->color[1] = 0.775;
|
||||
dl->color[2] = 0.25;
|
||||
dl->channelfade[0] = 0.196;
|
||||
dl->channelfade[1] = 0.23;
|
||||
dl->channelfade[2] = 0.12;
|
||||
dl->color[0] = 4.0;
|
||||
dl->color[1] = 2.0;
|
||||
dl->color[2] = 0.5;
|
||||
dl->channelfade[0] = 0.784;
|
||||
dl->channelfade[1] = 0.92;
|
||||
dl->channelfade[2] = 0.48;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1741,12 +1741,13 @@ void CLDP_ParseTrailParticles(void)
|
|||
end[1] = MSG_ReadCoord();
|
||||
end[2] = MSG_ReadCoord();
|
||||
|
||||
effectindex = P_FindParticleType(COM_Effectinfo_ForNumber(effectindex));
|
||||
|
||||
if (entityindex && (unsigned int)entityindex < MAX_EDICTS)
|
||||
ts = &cl.lerpents[entityindex].trailstate;
|
||||
else
|
||||
ts = NULL;
|
||||
|
||||
effectindex = P_FindParticleType(COM_Effectinfo_ForNumber(effectindex));
|
||||
if (P_ParticleTrail(start, end, effectindex, entityindex, ts))
|
||||
P_ParticleTrail(start, end, rt_blood, entityindex, ts);
|
||||
}
|
||||
|
@ -1774,6 +1775,7 @@ void CLDP_ParsePointParticles(qboolean compact)
|
|||
}
|
||||
|
||||
effectindex = P_FindParticleType(COM_Effectinfo_ForNumber(effectindex));
|
||||
|
||||
if (P_RunParticleEffectType(org, dir, count, effectindex))
|
||||
P_RunParticleEffect (org, dir, 15, 15);
|
||||
}
|
||||
|
|
|
@ -741,7 +741,7 @@ char *Media_NextTrack(int musicchannelnum)
|
|||
|
||||
|
||||
//Avi files are specific to windows. Bit of a bummer really.
|
||||
#if defined(_WIN32) && !defined(__GNUC__)
|
||||
#if defined(_WIN32)
|
||||
#define WINAVI
|
||||
#endif
|
||||
|
||||
|
@ -773,11 +773,114 @@ char *Media_NextTrack(int musicchannelnum)
|
|||
#ifdef WINAVI
|
||||
#undef CDECL //windows is stupid at times.
|
||||
#define CDECL __cdecl
|
||||
|
||||
#if 0
|
||||
#include <vfw.h>
|
||||
#else
|
||||
typedef struct
|
||||
{
|
||||
DWORD fccType;
|
||||
DWORD fccHandler;
|
||||
DWORD dwFlags;
|
||||
DWORD dwCaps;
|
||||
WORD wPriority;
|
||||
WORD wLanguage;
|
||||
DWORD dwScale;
|
||||
DWORD dwRate;
|
||||
DWORD dwStart;
|
||||
DWORD dwLength;
|
||||
DWORD dwInitialFrames;
|
||||
DWORD dwSuggestedBufferSize;
|
||||
DWORD dwQuality;
|
||||
DWORD dwSampleSize;
|
||||
RECT rcFrame;
|
||||
DWORD dwEditCount;
|
||||
DWORD dwFormatChangeCount;
|
||||
TCHAR szName[64];
|
||||
} AVISTREAMINFOA, *LPAVISTREAMINFOA;
|
||||
typedef struct AVISTREAM *PAVISTREAM;
|
||||
typedef struct AVIFILE *PAVIFILE;
|
||||
typedef struct GETFRAME *PGETFRAME;
|
||||
typedef struct
|
||||
{
|
||||
DWORD fccType;
|
||||
DWORD fccHandler;
|
||||
DWORD dwKeyFrameEvery;
|
||||
DWORD dwQuality;
|
||||
DWORD dwBytesPerSecond;
|
||||
DWORD dwFlags;
|
||||
LPVOID lpFormat;
|
||||
DWORD cbFormat;
|
||||
LPVOID lpParms;
|
||||
DWORD cbParms;
|
||||
DWORD dwInterleaveEvery;
|
||||
} AVICOMPRESSOPTIONS;
|
||||
#define streamtypeVIDEO mmioFOURCC('v', 'i', 'd', 's')
|
||||
#define streamtypeAUDIO mmioFOURCC('a', 'u', 'd', 's')
|
||||
#define AVISTREAMREAD_CONVENIENT (-1L)
|
||||
#define AVIIF_KEYFRAME 0x00000010L
|
||||
#endif
|
||||
|
||||
int aviinited;
|
||||
ULONG (WINAPI *qAVIStreamRelease) (PAVISTREAM pavi);
|
||||
HRESULT (WINAPI *qAVIStreamEndStreaming) (PAVISTREAM pavi);
|
||||
HRESULT (WINAPI *qAVIStreamGetFrameClose) (PGETFRAME pg);
|
||||
HRESULT (WINAPI *qAVIStreamRead) (PAVISTREAM pavi, LONG lStart, LONG lSamples, LPVOID lpBuffer, LONG cbBuffer, LONG FAR * plBytes, LONG FAR * plSamples);
|
||||
LPVOID (WINAPI *qAVIStreamGetFrame) (PGETFRAME pg, LONG lPos);
|
||||
HRESULT (WINAPI *qAVIStreamReadFormat) (PAVISTREAM pavi, LONG lPos,LPVOID lpFormat,LONG FAR *lpcbFormat);
|
||||
LONG (WINAPI *qAVIStreamStart) (PAVISTREAM pavi);
|
||||
PGETFRAME(WINAPI*qAVIStreamGetFrameOpen) (PAVISTREAM pavi, LPBITMAPINFOHEADER lpbiWanted);
|
||||
HRESULT (WINAPI *qAVIStreamBeginStreaming) (PAVISTREAM pavi, LONG lStart, LONG lEnd, LONG lRate);
|
||||
LONG (WINAPI *qAVIStreamSampleToTime) (PAVISTREAM pavi, LONG lSample);
|
||||
LONG (WINAPI *qAVIStreamLength) (PAVISTREAM pavi);
|
||||
HRESULT (WINAPI *qAVIStreamInfoA) (PAVISTREAM pavi, LPAVISTREAMINFOA psi, LONG lSize);
|
||||
ULONG (WINAPI *qAVIFileRelease) (PAVIFILE pfile);
|
||||
HRESULT (WINAPI *qAVIFileGetStream) (PAVIFILE pfile, PAVISTREAM FAR * ppavi, DWORD fccType, LONG lParam);
|
||||
HRESULT (WINAPI *qAVIFileOpenA) (PAVIFILE FAR *ppfile, LPCSTR szFile, UINT uMode, LPCLSID lpHandler);
|
||||
void (WINAPI *qAVIFileInit) (void);
|
||||
HRESULT (WINAPI *qAVIStreamWrite) (PAVISTREAM pavi, LONG lStart, LONG lSamples, LPVOID lpBuffer, LONG cbBuffer, DWORD dwFlags, LONG FAR *plSampWritten, LONG FAR *plBytesWritten);
|
||||
HRESULT (WINAPI *qAVIStreamSetFormat) (PAVISTREAM pavi, LONG lPos,LPVOID lpFormat,LONG cbFormat);
|
||||
HRESULT (WINAPI *qAVIMakeCompressedStream) (PAVISTREAM FAR * ppsCompressed, PAVISTREAM ppsSource, AVICOMPRESSOPTIONS FAR * lpOptions, CLSID FAR *pclsidHandler);
|
||||
HRESULT (WINAPI *qAVIFileCreateStreamA) (PAVIFILE pfile, PAVISTREAM FAR *ppavi, AVISTREAMINFOA FAR * psi);
|
||||
|
||||
#pragma comment( lib, "vfw32.lib" )
|
||||
qboolean qAVIStartup(void)
|
||||
{
|
||||
static int aviinited;
|
||||
static dllhandle_t *avimodule;
|
||||
if (!aviinited)
|
||||
{
|
||||
dllfunction_t funcs[] =
|
||||
{
|
||||
{(void*)&qAVIFileInit, "AVIFileInit"},
|
||||
{(void*)&qAVIStreamRelease, "AVIStreamRelease"},
|
||||
{(void*)&qAVIStreamEndStreaming, "AVIStreamEndStreaming"},
|
||||
{(void*)&qAVIStreamGetFrameClose, "AVIStreamGetFrameClose"},
|
||||
{(void*)&qAVIStreamRead, "AVIStreamRead"},
|
||||
{(void*)&qAVIStreamGetFrame, "AVIStreamGetFrame"},
|
||||
{(void*)&qAVIStreamReadFormat, "AVIStreamReadFormat"},
|
||||
{(void*)&qAVIStreamStart, "AVIStreamStart"},
|
||||
{(void*)&qAVIStreamGetFrameOpen, "AVIStreamGetFrameOpen"},
|
||||
{(void*)&qAVIStreamBeginStreaming, "AVIStreamBeginStreaming"},
|
||||
{(void*)&qAVIStreamSampleToTime, "AVIStreamSampleToTime"},
|
||||
{(void*)&qAVIStreamLength, "AVIStreamLength"},
|
||||
{(void*)&qAVIStreamInfoA, "AVIStreamInfoA"},
|
||||
{(void*)&qAVIFileRelease, "AVIFileRelease"},
|
||||
{(void*)&qAVIFileGetStream, "AVIFileGetStream"},
|
||||
{(void*)&qAVIFileOpenA, "AVIFileOpenA"},
|
||||
{(void*)&qAVIStreamWrite, "AVIStreamWrite"},
|
||||
{(void*)&qAVIStreamSetFormat, "AVIStreamSetFormat"},
|
||||
{(void*)&qAVIMakeCompressedStream, "AVIMakeCompressedStream"},
|
||||
{(void*)&qAVIFileCreateStreamA, "AVIFileCreateStreamA"},
|
||||
{NULL,NULL}
|
||||
};
|
||||
aviinited = true;
|
||||
avimodule = Sys_LoadLibrary("avifil32.dll", funcs);
|
||||
|
||||
if (avimodule)
|
||||
qAVIFileInit();
|
||||
}
|
||||
|
||||
return avimodule?true:false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define MFT_CAPTURE 5 //fixme
|
||||
|
@ -822,7 +925,7 @@ struct cin_s {
|
|||
|
||||
#ifdef WINAVI
|
||||
struct {
|
||||
AVISTREAMINFO psi; // Pointer To A Structure Containing Stream Info
|
||||
AVISTREAMINFOA psi; // Pointer To A Structure Containing Stream Info
|
||||
PAVISTREAM pavivideo;
|
||||
PAVISTREAM pavisound;
|
||||
PAVIFILE pavi;
|
||||
|
@ -876,9 +979,9 @@ shader_t *videoshader;
|
|||
#ifdef WINAVI
|
||||
void Media_WINAVI_Shutdown(struct cin_s *cin)
|
||||
{
|
||||
AVIStreamGetFrameClose(cin->avi.pgf);
|
||||
AVIStreamEndStreaming(cin->avi.pavivideo);
|
||||
AVIStreamRelease(cin->avi.pavivideo);
|
||||
qAVIStreamGetFrameClose(cin->avi.pgf);
|
||||
qAVIStreamEndStreaming(cin->avi.pavivideo);
|
||||
qAVIStreamRelease(cin->avi.pavivideo);
|
||||
//we don't need to free the file (we freed it immediatly after getting the stream handles)
|
||||
}
|
||||
qboolean Media_WinAvi_DecodeFrame(cin_t *cin, qboolean nosound)
|
||||
|
@ -892,6 +995,9 @@ qboolean Media_WinAvi_DecodeFrame(cin_t *cin, qboolean nosound)
|
|||
newframe = (curtime - cin->filmstarttime)*cin->avi.filmfps;
|
||||
newframei = newframe;
|
||||
|
||||
if (newframei>=cin->avi.num_frames)
|
||||
cin->ended = true;
|
||||
|
||||
if (newframe == cin->currentframe)
|
||||
{
|
||||
cin->outunchanged = true;
|
||||
|
@ -904,18 +1010,18 @@ qboolean Media_WinAvi_DecodeFrame(cin_t *cin, qboolean nosound)
|
|||
cin->currentframe = newframei;
|
||||
Con_DPrintf("%i\n", newframei);
|
||||
|
||||
if (cin->currentframe>=cin->avi.num_frames)
|
||||
if (newframei>=cin->avi.num_frames)
|
||||
{
|
||||
return false;
|
||||
cin->filmstarttime = curtime;
|
||||
cin->currentframe = newframei = 0;
|
||||
cin->avi.soundpos = 0;
|
||||
}
|
||||
|
||||
lpbi = (LPBITMAPINFOHEADER)AVIStreamGetFrame(cin->avi.pgf, cin->currentframe); // Grab Data From The AVI Stream
|
||||
cin->currentframe++;
|
||||
lpbi = (LPBITMAPINFOHEADER)qAVIStreamGetFrame(cin->avi.pgf, cin->currentframe); // Grab Data From The AVI Stream
|
||||
if (!lpbi || lpbi->biBitCount != 24)//oops
|
||||
{
|
||||
SCR_SetUpToDrawConsole();
|
||||
R2D_ConsoleBackground(0, vid.height, true);
|
||||
Draw_FunString(0, 0, "Video stream is corrupt\n");
|
||||
cin->ended = true;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -931,14 +1037,13 @@ qboolean Media_WinAvi_DecodeFrame(cin_t *cin, qboolean nosound)
|
|||
LPBYTE pBuffer;
|
||||
LONG samples;
|
||||
|
||||
AVIStreamRead(cin->avi.pavisound, 0, AVISTREAMREAD_CONVENIENT,
|
||||
NULL, 0, &lSize, &samples);
|
||||
qAVIStreamRead(cin->avi.pavisound, 0, AVISTREAMREAD_CONVENIENT, NULL, 0, &lSize, &samples);
|
||||
|
||||
cin->avi.soundpos+=samples;
|
||||
|
||||
pBuffer = cin->framedata;
|
||||
|
||||
AVIStreamRead(cin->avi.pavisound, cin->avi.soundpos, AVISTREAMREAD_CONVENIENT, pBuffer, lSize, NULL, &samples);
|
||||
qAVIStreamRead(cin->avi.pavisound, cin->avi.soundpos, AVISTREAMREAD_CONVENIENT, pBuffer, lSize, NULL, &samples);
|
||||
|
||||
S_RawAudio(-1, pBuffer, cin->avi.pWaveFormat->nSamplesPerSec, samples, cin->avi.pWaveFormat->nChannels, 2);
|
||||
}
|
||||
|
@ -948,13 +1053,15 @@ cin_t *Media_WinAvi_TryLoad(char *name)
|
|||
{
|
||||
cin_t *cin;
|
||||
PAVIFILE pavi;
|
||||
flocation_t loc;
|
||||
|
||||
if (!aviinited)
|
||||
{
|
||||
aviinited=true;
|
||||
AVIFileInit();
|
||||
}
|
||||
if (!AVIFileOpen(&pavi, name, OF_READ, NULL))//!AVIStreamOpenFromFile(&pavi, name, streamtypeVIDEO, 0, OF_READ, NULL))
|
||||
if (!qAVIStartup())
|
||||
return NULL;
|
||||
|
||||
|
||||
FS_FLocateFile(name, FSLFRT_DEPTH_OSONLY, &loc);
|
||||
|
||||
if (!loc.offset && !qAVIFileOpenA(&pavi, loc.rawname, OF_READ, NULL))//!AVIStreamOpenFromFile(&pavi, name, streamtypeVIDEO, 0, OF_READ, NULL))
|
||||
{
|
||||
int filmwidth;
|
||||
int filmheight;
|
||||
|
@ -963,32 +1070,41 @@ cin_t *Media_WinAvi_TryLoad(char *name)
|
|||
cin->filmtype = MFT_AVI;
|
||||
cin->avi.pavi = pavi;
|
||||
|
||||
if (AVIFileGetStream(cin->avi.pavi, &cin->avi.pavivideo, streamtypeVIDEO, 0)) //retrieve video stream
|
||||
if (qAVIFileGetStream(cin->avi.pavi, &cin->avi.pavivideo, streamtypeVIDEO, 0)) //retrieve video stream
|
||||
{
|
||||
AVIFileRelease(pavi);
|
||||
qAVIFileRelease(pavi);
|
||||
Con_Printf("%s contains no video stream\n", name);
|
||||
return NULL;
|
||||
}
|
||||
if (AVIFileGetStream(cin->avi.pavi, &cin->avi.pavisound, streamtypeAUDIO, 0)) //retrieve audio stream
|
||||
if (qAVIFileGetStream(cin->avi.pavi, &cin->avi.pavisound, streamtypeAUDIO, 0)) //retrieve audio stream
|
||||
{
|
||||
Con_DPrintf("%s contains no audio stream\n", name);
|
||||
cin->avi.pavisound=NULL;
|
||||
}
|
||||
AVIFileRelease(cin->avi.pavi);
|
||||
qAVIFileRelease(cin->avi.pavi);
|
||||
|
||||
//play with video
|
||||
AVIStreamInfo(cin->avi.pavivideo, &cin->avi.psi, sizeof(cin->avi.psi));
|
||||
qAVIStreamInfoA(cin->avi.pavivideo, &cin->avi.psi, sizeof(cin->avi.psi));
|
||||
filmwidth=cin->avi.psi.rcFrame.right-cin->avi.psi.rcFrame.left; // Width Is Right Side Of Frame Minus Left
|
||||
filmheight=cin->avi.psi.rcFrame.bottom-cin->avi.psi.rcFrame.top; // Height Is Bottom Of Frame Minus Top
|
||||
cin->framedata = BZ_Malloc(filmwidth*filmheight*4);
|
||||
|
||||
cin->avi.num_frames=AVIStreamLength(cin->avi.pavivideo); // The Last Frame Of The Stream
|
||||
cin->avi.filmfps=1000.0f*(float)cin->avi.num_frames/(float)AVIStreamSampleToTime(cin->avi.pavivideo,cin->avi.num_frames); // Calculate Rough Milliseconds Per Frame
|
||||
cin->avi.num_frames=qAVIStreamLength(cin->avi.pavivideo); // The Last Frame Of The Stream
|
||||
cin->avi.filmfps=1000.0f*(float)cin->avi.num_frames/(float)qAVIStreamSampleToTime(cin->avi.pavivideo,cin->avi.num_frames); // Calculate Rough Milliseconds Per Frame
|
||||
|
||||
qAVIStreamBeginStreaming(cin->avi.pavivideo, 0, cin->avi.num_frames, 100);
|
||||
|
||||
AVIStreamBeginStreaming(cin->avi.pavivideo, 0, cin->avi.num_frames, 100);
|
||||
cin->avi.pgf=qAVIStreamGetFrameOpen(cin->avi.pavivideo, NULL);
|
||||
|
||||
cin->avi.pgf=AVIStreamGetFrameOpen(cin->avi.pavivideo, NULL);
|
||||
if (!cin->avi.pgf)
|
||||
{
|
||||
Con_Printf("AVIStreamGetFrameOpen failed. Please install codec for '%c%c%c%c'.\n",
|
||||
((unsigned char*)&cin->avi.psi.fccHandler)[0],
|
||||
((unsigned char*)&cin->avi.psi.fccHandler)[1],
|
||||
((unsigned char*)&cin->avi.psi.fccHandler)[2],
|
||||
((unsigned char*)&cin->avi.psi.fccHandler)[3]
|
||||
);
|
||||
}
|
||||
|
||||
cin->currentframe=0;
|
||||
cin->filmstarttime = Sys_DoubleTime();
|
||||
|
@ -1001,7 +1117,7 @@ cin_t *Media_WinAvi_TryLoad(char *name)
|
|||
{
|
||||
LONG lSize;
|
||||
LPBYTE pChunk;
|
||||
AVIStreamRead(cin->avi.pavisound, 0, AVISTREAMREAD_CONVENIENT, NULL, 0, &lSize, NULL);
|
||||
qAVIStreamRead(cin->avi.pavisound, 0, AVISTREAMREAD_CONVENIENT, NULL, 0, &lSize, NULL);
|
||||
|
||||
if (!lSize)
|
||||
cin->avi.pWaveFormat = NULL;
|
||||
|
@ -1011,7 +1127,7 @@ cin_t *Media_WinAvi_TryLoad(char *name)
|
|||
pChunk = BZ_Malloc(sizeof(qbyte)*lSize);
|
||||
|
||||
|
||||
if(AVIStreamReadFormat(cin->avi.pavisound, AVIStreamStart(cin->avi.pavisound), pChunk, &lSize))
|
||||
if(qAVIStreamReadFormat(cin->avi.pavisound, qAVIStreamStart(cin->avi.pavisound), pChunk, &lSize))
|
||||
{
|
||||
// error
|
||||
Con_Printf("Failiure reading sound info\n");
|
||||
|
@ -1022,13 +1138,13 @@ cin_t *Media_WinAvi_TryLoad(char *name)
|
|||
if (!cin->avi.pWaveFormat)
|
||||
{
|
||||
Con_Printf("VFW is broken\n");
|
||||
AVIStreamRelease(cin->avi.pavisound);
|
||||
qAVIStreamRelease(cin->avi.pavisound);
|
||||
cin->avi.pavisound=NULL;
|
||||
}
|
||||
else if (cin->avi.pWaveFormat->wFormatTag != 1)
|
||||
{
|
||||
Con_Printf("Audio stream is not PCM\n"); //FIXME: so that it no longer is...
|
||||
AVIStreamRelease(cin->avi.pavisound);
|
||||
qAVIStreamRelease(cin->avi.pavisound);
|
||||
cin->avi.pavisound=NULL;
|
||||
}
|
||||
|
||||
|
@ -1994,7 +2110,7 @@ void Media_RecordFrame (void)
|
|||
framebuffer[i+2] = temp;
|
||||
}
|
||||
//write it
|
||||
hr = AVIStreamWrite(recordavi_video_stream, captureframe++, 1, framebuffer, vid.pixelwidth*vid.pixelheight * 3, ((captureframe%15) == 0)?AVIIF_KEYFRAME:0, NULL, NULL);
|
||||
hr = qAVIStreamWrite(recordavi_video_stream, captureframe++, 1, framebuffer, vid.pixelwidth*vid.pixelheight * 3, ((captureframe%15) == 0)?AVIIF_KEYFRAME:0, NULL, NULL);
|
||||
if (FAILED(hr)) Con_Printf("Recoring error\n");
|
||||
}
|
||||
#endif /* WINAVI */
|
||||
|
@ -2082,11 +2198,11 @@ static void MSD_Submit(soundcardinfo_t *sc, int start, int end)
|
|||
int partialsamplestosubmit;
|
||||
//wraped, two chunks to send
|
||||
partialsamplestosubmit = ((sc->sn.samples/sc->sn.numchannels)) - offset;
|
||||
AVIStreamWrite(recordavi_uncompressed_audio_stream, recordavi_audio_frame_counter++, 1, sc->sn.buffer+offset*bytespersample, partialsamplestosubmit*bytespersample, AVIIF_KEYFRAME, NULL, NULL);
|
||||
qAVIStreamWrite(recordavi_uncompressed_audio_stream, recordavi_audio_frame_counter++, 1, sc->sn.buffer+offset*bytespersample, partialsamplestosubmit*bytespersample, AVIIF_KEYFRAME, NULL, NULL);
|
||||
samplestosubmit -= partialsamplestosubmit;
|
||||
offset = 0;
|
||||
}
|
||||
AVIStreamWrite(recordavi_uncompressed_audio_stream, recordavi_audio_frame_counter++, 1, sc->sn.buffer+offset*bytespersample, samplestosubmit*bytespersample, AVIIF_KEYFRAME, NULL, NULL);
|
||||
qAVIStreamWrite(recordavi_uncompressed_audio_stream, recordavi_audio_frame_counter++, 1, sc->sn.buffer+offset*bytespersample, samplestosubmit*bytespersample, AVIIF_KEYFRAME, NULL, NULL);
|
||||
#endif /* WINAVI */
|
||||
break;
|
||||
case CT_NONE:
|
||||
|
@ -2154,10 +2270,10 @@ void Media_InitFakeSoundDevice (int channels, int samplebits)
|
|||
void Media_StopRecordFilm_f (void)
|
||||
{
|
||||
#if defined(WINAVI)
|
||||
if (recordavi_uncompressed_video_stream) AVIStreamRelease(recordavi_uncompressed_video_stream);
|
||||
if (recordavi_compressed_video_stream) AVIStreamRelease(recordavi_compressed_video_stream);
|
||||
if (recordavi_uncompressed_audio_stream) AVIStreamRelease(recordavi_uncompressed_audio_stream);
|
||||
if (recordavi_file) AVIFileRelease(recordavi_file);
|
||||
if (recordavi_uncompressed_video_stream) qAVIStreamRelease(recordavi_uncompressed_video_stream);
|
||||
if (recordavi_compressed_video_stream) qAVIStreamRelease(recordavi_compressed_video_stream);
|
||||
if (recordavi_uncompressed_audio_stream) qAVIStreamRelease(recordavi_uncompressed_audio_stream);
|
||||
if (recordavi_file) qAVIFileRelease(recordavi_file);
|
||||
|
||||
recordavi_uncompressed_video_stream=NULL;
|
||||
recordavi_compressed_video_stream = NULL;
|
||||
|
@ -2263,7 +2379,7 @@ void Media_RecordFilm_f (void)
|
|||
{
|
||||
HRESULT hr;
|
||||
BITMAPINFOHEADER bitmap_info_header;
|
||||
AVISTREAMINFO stream_header;
|
||||
AVISTREAMINFOA stream_header;
|
||||
FILE *f;
|
||||
char aviname[256];
|
||||
char nativepath[256];
|
||||
|
@ -2273,10 +2389,10 @@ void Media_RecordFilm_f (void)
|
|||
else
|
||||
recordavi_codec_fourcc = 0;
|
||||
|
||||
if (!aviinited)
|
||||
if (!qAVIStartup())
|
||||
{
|
||||
aviinited=true;
|
||||
AVIFileInit();
|
||||
Con_Printf("vfw support not available.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/*convert to foo.avi*/
|
||||
|
@ -2293,7 +2409,7 @@ void Media_RecordFilm_f (void)
|
|||
unlink(nativepath);
|
||||
}
|
||||
|
||||
hr = AVIFileOpen(&recordavi_file, nativepath, OF_WRITE | OF_CREATE, NULL);
|
||||
hr = qAVIFileOpenA(&recordavi_file, nativepath, OF_WRITE | OF_CREATE, NULL);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Con_Printf("Failed to open %s\n", nativepath);
|
||||
|
@ -2318,7 +2434,7 @@ void Media_RecordFilm_f (void)
|
|||
stream_header.dwRate = (unsigned long)(0.5 + 100.0/recordavi_frametime);
|
||||
SetRect(&stream_header.rcFrame, 0, 0, vid.pixelwidth, vid.pixelheight);
|
||||
|
||||
hr = AVIFileCreateStream(recordavi_file, &recordavi_uncompressed_video_stream, &stream_header);
|
||||
hr = qAVIFileCreateStreamA(recordavi_file, &recordavi_uncompressed_video_stream, &stream_header);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Con_Printf("Couldn't initialise the stream, check codec\n");
|
||||
|
@ -2334,7 +2450,7 @@ void Media_RecordFilm_f (void)
|
|||
opts.fccType = stream_header.fccType;
|
||||
opts.fccHandler = recordavi_codec_fourcc;
|
||||
// Make the stream according to compression
|
||||
hr = AVIMakeCompressedStream(&recordavi_compressed_video_stream, recordavi_uncompressed_video_stream, &opts, NULL);
|
||||
hr = qAVIMakeCompressedStream(&recordavi_compressed_video_stream, recordavi_uncompressed_video_stream, &opts, NULL);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Con_Printf("Failed to init compressor\n");
|
||||
|
@ -2344,7 +2460,7 @@ void Media_RecordFilm_f (void)
|
|||
}
|
||||
|
||||
|
||||
hr = AVIStreamSetFormat(recordavi_video_stream, 0, &bitmap_info_header, sizeof(BITMAPINFOHEADER));
|
||||
hr = qAVIStreamSetFormat(recordavi_video_stream, 0, &bitmap_info_header, sizeof(BITMAPINFOHEADER));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Con_Printf("Failed to set format\n");
|
||||
|
@ -2375,10 +2491,10 @@ void Media_RecordFilm_f (void)
|
|||
stream_header.dwRate = stream_header.dwScale * (unsigned long)recordavi_wave_format.nSamplesPerSec;
|
||||
stream_header.dwSampleSize = recordavi_wave_format.nBlockAlign;
|
||||
|
||||
hr = AVIFileCreateStream(recordavi_file, &recordavi_uncompressed_audio_stream, &stream_header);
|
||||
hr = qAVIFileCreateStreamA(recordavi_file, &recordavi_uncompressed_audio_stream, &stream_header);
|
||||
if (FAILED(hr)) return;
|
||||
|
||||
hr = AVIStreamSetFormat(recordavi_uncompressed_audio_stream, 0, &recordavi_wave_format, sizeof(WAVEFORMATEX));
|
||||
hr = qAVIStreamSetFormat(recordavi_uncompressed_audio_stream, 0, &recordavi_wave_format, sizeof(WAVEFORMATEX));
|
||||
if (FAILED(hr)) return;
|
||||
|
||||
Media_InitFakeSoundDevice(recordavi_wave_format.nChannels, recordavi_wave_format.wBitsPerSample);
|
||||
|
|
|
@ -720,7 +720,7 @@ void M_Menu_Textures_f (void)
|
|||
};
|
||||
|
||||
extern cvar_t gl_load24bit, gl_specular, gl_detail, gl_compress, gl_picmip, gl_picmip2d, gl_max_size, r_drawflat, r_glsl_offsetmapping;
|
||||
extern cvar_t gl_texture_anisotropic_filtering, gl_texturemode, gl_texturemode2d;
|
||||
extern cvar_t gl_texture_anisotropic_filtering, gl_texturemode, gl_texturemode2d, gl_mipcap;
|
||||
int y;
|
||||
menubulk_t bulk[] =
|
||||
{
|
||||
|
@ -740,6 +740,7 @@ void M_Menu_Textures_f (void)
|
|||
MB_CHECKBOXCVAR("Texture Compression", gl_compress, 0), // merge the save compressed tex options into here?
|
||||
MB_SLIDER("3D Picmip", gl_picmip, 0, 16, 1, NULL),
|
||||
MB_SLIDER("2D Picmip", gl_picmip2d, 0, 16, 1, NULL),
|
||||
MB_SLIDER("World Mipcap", gl_mipcap, 0, 3, 1, NULL),
|
||||
MB_COMBOCVAR("Max Texture Size", gl_max_size, texturesizeoptions, texturesizeoptions, NULL),
|
||||
MB_END()
|
||||
};
|
||||
|
|
|
@ -4922,7 +4922,7 @@ qboolean CSQC_Init (qboolean anycsqc, unsigned int checksum)
|
|||
PR_ExecuteProgram(csqcprogs, csqcg.init_function);
|
||||
}
|
||||
|
||||
Con_Printf("Loaded csqc\n");
|
||||
Con_DPrintf("Loaded csqc\n");
|
||||
csqcmapentitydataloaded = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -275,7 +275,7 @@ enum imageflags
|
|||
IF_CUBEMAPEXTRA = 1<<8,
|
||||
IF_TEXTYPE = (1<<6) | (1<<7) | (1<<8), /*0=2d, 1=3d, 2-7=cubeface*/
|
||||
IF_TEXTYPESHIFT = 6, /*0=2d, 1=3d, 2-7=cubeface*/
|
||||
|
||||
IF_MIPCAP = 1<<9,
|
||||
IF_REPLACE = 1<<30,
|
||||
IF_SUBDIRONLY = 1<<31
|
||||
};
|
||||
|
@ -430,7 +430,7 @@ extern cvar_t gl_poly;
|
|||
extern cvar_t gl_affinemodels;
|
||||
extern cvar_t gl_nohwblend;
|
||||
extern cvar_t gl_reporttjunctions;
|
||||
extern cvar_t r_flashblend, r_flashblendscale;
|
||||
extern cvar_t r_coronas, r_flashblend, r_flashblendscale;
|
||||
extern cvar_t r_lightstylesmooth;
|
||||
extern cvar_t r_lightstylesmooth_limit;
|
||||
extern cvar_t r_lightstylespeed;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "pr_common.h"
|
||||
#include "gl_draw.h"
|
||||
#include "shader.h"
|
||||
#include "glquake.h"
|
||||
#include <string.h>
|
||||
|
||||
|
||||
|
@ -34,6 +35,7 @@ extern int gl_anisotropy_factor;
|
|||
void SCR_Viewsize_Callback (struct cvar_s *var, char *oldvalue);
|
||||
void SCR_Fov_Callback (struct cvar_s *var, char *oldvalue);
|
||||
#if defined(GLQUAKE)
|
||||
void GL_Mipcap_Callback (struct cvar_s *var, char *oldvalue);
|
||||
void GL_Texturemode_Callback (struct cvar_s *var, char *oldvalue);
|
||||
void GL_Texturemode2d_Callback (struct cvar_s *var, char *oldvalue);
|
||||
void GL_Texture_Anisotropic_Filtering_Callback (struct cvar_s *var, char *oldvalue);
|
||||
|
@ -88,6 +90,8 @@ cvar_t r_fb_models = CVARAF ("r_fb_models", "1",
|
|||
"gl_fb_models", CVAR_SEMICHEAT|CVAR_RENDERERLATCH);
|
||||
cvar_t r_skin_overlays = SCVARF ("r_skin_overlays", "1",
|
||||
CVAR_SEMICHEAT|CVAR_RENDERERLATCH);
|
||||
cvar_t r_coronas = SCVARF ("r_coronas", "0",
|
||||
CVAR_ARCHIVE);
|
||||
cvar_t r_flashblend = SCVARF ("gl_flashblend", "0",
|
||||
CVAR_ARCHIVE);
|
||||
cvar_t r_flashblendscale = SCVARF ("gl_flashblendscale", "0.35",
|
||||
|
@ -284,6 +288,9 @@ cvar_t gl_texture_anisotropic_filtering = CVARFC("gl_texture_anisotropic_filter
|
|||
cvar_t gl_texturemode = CVARFC("gl_texturemode", "GL_LINEAR_MIPMAP_NEAREST",
|
||||
CVAR_ARCHIVE | CVAR_RENDERERCALLBACK,
|
||||
GL_Texturemode_Callback);
|
||||
cvar_t gl_mipcap = CVARFC("d_mipcap", "0 1000",
|
||||
CVAR_ARCHIVE | CVAR_RENDERERCALLBACK,
|
||||
GL_Mipcap_Callback);
|
||||
cvar_t gl_texturemode2d = CVARFC("gl_texturemode2d", "GL_LINEAR",
|
||||
CVAR_ARCHIVE | CVAR_RENDERERCALLBACK,
|
||||
GL_Texturemode2d_Callback);
|
||||
|
@ -367,11 +374,6 @@ void GLRenderer_Init(void)
|
|||
Cvar_Register (&gl_maxshadowlights, GLRENDEREROPTIONS);
|
||||
Cvar_Register (&r_shadow_bumpscale_basetexture, GLRENDEREROPTIONS);
|
||||
Cvar_Register (&r_shadow_bumpscale_bumpmap, GLRENDEREROPTIONS);
|
||||
Cvar_Register (&r_shadow_realtime_world, GLRENDEREROPTIONS);
|
||||
Cvar_Register (&r_shadow_realtime_world_shadows, GLRENDEREROPTIONS);
|
||||
Cvar_Register (&r_shadow_realtime_dlight, GLRENDEREROPTIONS);
|
||||
Cvar_Register (&r_shadow_realtime_dlight_shadows, GLRENDEREROPTIONS);
|
||||
Cvar_Register (&r_shadow_realtime_world_lightmaps, GLRENDEREROPTIONS);
|
||||
|
||||
Cvar_Register (&gl_reporttjunctions, GLRENDEREROPTIONS);
|
||||
|
||||
|
@ -396,6 +398,7 @@ void GLRenderer_Init(void)
|
|||
Cvar_Register (&gl_picmip, GLRENDEREROPTIONS);
|
||||
Cvar_Register (&gl_picmip2d, GLRENDEREROPTIONS);
|
||||
|
||||
Cvar_Register (&gl_mipcap, GLRENDEREROPTIONS);
|
||||
Cvar_Register (&gl_texturemode, GLRENDEREROPTIONS);
|
||||
Cvar_Register (&gl_texturemode2d, GLRENDEREROPTIONS);
|
||||
Cvar_Register (&gl_texture_anisotropic_filtering, GLRENDEREROPTIONS);
|
||||
|
@ -487,6 +490,10 @@ void Renderer_Init(void)
|
|||
Cmd_AddCommand("setrenderer", R_SetRenderer_f);
|
||||
Cmd_AddCommand("vid_restart", R_RestartRenderer_f);
|
||||
|
||||
#ifdef RTLIGHTS
|
||||
Cmd_AddCommand ("r_editlights_reload", R_ReloadRTLights_f);
|
||||
Cmd_AddCommand ("r_editlights_save", R_SaveRTLights_f);
|
||||
#endif
|
||||
Cmd_AddCommand("r_dumpshaders", Shader_WriteOutGenerics_f);
|
||||
|
||||
#if defined(GLQUAKE) || defined(D3DQUAKE)
|
||||
|
@ -537,9 +544,17 @@ void Renderer_Init(void)
|
|||
Cvar_Register(&r_stains, GRAPHICALNICETIES);
|
||||
Cvar_Register(&r_stainfadetime, GRAPHICALNICETIES);
|
||||
Cvar_Register(&r_stainfadeammount, GRAPHICALNICETIES);
|
||||
Cvar_Register(&r_lightprepass, GRAPHICALNICETIES);
|
||||
Cvar_Register (&r_flashblend, GLRENDEREROPTIONS);
|
||||
Cvar_Register (&r_flashblendscale, GLRENDEREROPTIONS);
|
||||
Cvar_Register(&r_lightprepass, GLRENDEREROPTIONS);
|
||||
Cvar_Register (&r_coronas, GRAPHICALNICETIES);
|
||||
Cvar_Register (&r_flashblend, GRAPHICALNICETIES);
|
||||
Cvar_Register (&r_flashblendscale, GRAPHICALNICETIES);
|
||||
|
||||
Cvar_Register (&r_shadow_realtime_world, GRAPHICALNICETIES);
|
||||
Cvar_Register (&r_shadow_realtime_world_shadows, GRAPHICALNICETIES);
|
||||
Cvar_Register (&r_shadow_realtime_dlight, GRAPHICALNICETIES);
|
||||
Cvar_Register (&r_shadow_realtime_dlight_shadows, GRAPHICALNICETIES);
|
||||
Cvar_Register (&r_shadow_realtime_world_lightmaps, GRAPHICALNICETIES);
|
||||
|
||||
|
||||
Cvar_Register(&scr_viewsize, SCREENOPTIONS);
|
||||
Cvar_Register(&scr_fov, SCREENOPTIONS);
|
||||
|
@ -1942,9 +1957,10 @@ qboolean R_CullEntityBox(entity_t *e, vec3_t modmins, vec3_t modmaxs)
|
|||
|
||||
#if 1
|
||||
float mrad = 0, v;
|
||||
static vec3_t identaxis[3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
|
||||
|
||||
if (!memcmp(e->axis, identaxis, sizeof(identaxis)))
|
||||
if (e->axis[0][0]==1 && e->axis[0][1]==0 && e->axis[0][1]==0 &&
|
||||
e->axis[1][0]==0 && e->axis[1][1]==1 && e->axis[1][1]==0 &&
|
||||
e->axis[2][0]==0 && e->axis[2][1]==0 && e->axis[2][1]==1)
|
||||
{
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
|
|
|
@ -18,6 +18,8 @@ extern LPDIRECT3DDEVICE9 pD3DDev9;
|
|||
|
||||
extern float d3d_trueprojection[16];
|
||||
|
||||
static void BE_RotateForEntity (const entity_t *e, const model_t *mod);
|
||||
|
||||
/*========================================== tables for deforms =====================================*/
|
||||
#define frand() (rand()*(1.0/RAND_MAX))
|
||||
#define FTABLE_SIZE 1024
|
||||
|
@ -119,7 +121,9 @@ typedef struct
|
|||
unsigned int flags;
|
||||
|
||||
float curtime;
|
||||
const entity_t *curentity;
|
||||
const entity_t *curentity;
|
||||
const dlight_t *curdlight;
|
||||
vec3_t curdlight_colours;
|
||||
shader_t *curshader;
|
||||
texnums_t *curtexnums;
|
||||
texid_t curlightmap;
|
||||
|
@ -133,6 +137,7 @@ typedef struct
|
|||
unsigned int lastpasscount;
|
||||
vbo_t *batchvbo;
|
||||
|
||||
shader_t *shader_rtlight;
|
||||
texid_t curtex[MAX_TMUS];
|
||||
unsigned int tmuflags[MAX_TMUS];
|
||||
|
||||
|
@ -365,6 +370,15 @@ static void D3DBE_ApplyShaderBits(unsigned int bits)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (delta & (SBITS_MASK_BITS))
|
||||
{
|
||||
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_COLORWRITEENABLE,
|
||||
((bits&SBITS_MASK_RED)?0:D3DCOLORWRITEENABLE_RED) |
|
||||
((bits&SBITS_MASK_GREEN)?0:D3DCOLORWRITEENABLE_GREEN) |
|
||||
((bits&SBITS_MASK_BLUE)?0:D3DCOLORWRITEENABLE_BLUE) |
|
||||
((bits&SBITS_MASK_ALPHA)?0:D3DCOLORWRITEENABLE_ALPHA));
|
||||
}
|
||||
}
|
||||
|
||||
void D3DBE_Reset(qboolean before)
|
||||
|
@ -512,6 +526,21 @@ void D3DBE_Reset(qboolean before)
|
|||
}
|
||||
}
|
||||
|
||||
static const char LIGHTPASS_SHADER[] = "\
|
||||
{\n\
|
||||
program rtlight\n\
|
||||
{\n\
|
||||
map $diffuse\n\
|
||||
blendfunc add\n\
|
||||
}\n\
|
||||
{\n\
|
||||
map $normalmap\n\
|
||||
}\n\
|
||||
{\n\
|
||||
map $specular\n\
|
||||
}\n\
|
||||
}";
|
||||
|
||||
void D3DBE_Init(void)
|
||||
{
|
||||
be_maxpasses = MAX_TMUS;
|
||||
|
@ -527,6 +556,8 @@ void D3DBE_Init(void)
|
|||
|
||||
D3DBE_Reset(false);
|
||||
|
||||
shaderstate.shader_rtlight = R_RegisterShader("rtlight", LIGHTPASS_SHADER);
|
||||
|
||||
R_InitFlashblends();
|
||||
}
|
||||
|
||||
|
@ -1625,6 +1656,27 @@ static void BE_ApplyUniforms(program_t *prog, int permu)
|
|||
IDirect3DDevice9_SetVertexShaderConstantF(pD3DDev9, prog->parm[i].handle[permu], mvp, 4);
|
||||
}
|
||||
break;
|
||||
|
||||
case SP_LIGHTPOSITION:
|
||||
{
|
||||
/*light position in model space*/
|
||||
float inv[16];
|
||||
vec3_t t2;
|
||||
qboolean Matrix4_Invert(const float *m, float *out);
|
||||
|
||||
Matrix4_Invert(shaderstate.m_model, inv);
|
||||
Matrix4x4_CM_Transform3(inv, shaderstate.curdlight->origin, t2);
|
||||
IDirect3DDevice9_SetVertexShaderConstantF(pD3DDev9, prog->parm[i].handle[permu], t2, 3);
|
||||
break;
|
||||
}
|
||||
|
||||
case SP_LIGHTRADIUS:
|
||||
IDirect3DDevice9_SetPixelShaderConstantF(pD3DDev9, prog->parm[i].handle[permu], &shaderstate.curdlight->radius, 1);
|
||||
break;
|
||||
case SP_LIGHTCOLOUR:
|
||||
IDirect3DDevice9_SetPixelShaderConstantF(pD3DDev9, prog->parm[i].handle[permu], shaderstate.curdlight_colours, 3);
|
||||
break;
|
||||
|
||||
case SP_E_COLOURS:
|
||||
case SP_E_COLOURSIDENT:
|
||||
case SP_E_TOPCOLOURS:
|
||||
|
@ -1639,10 +1691,6 @@ static void BE_ApplyUniforms(program_t *prog, int permu)
|
|||
|
||||
case SP_RENDERTEXTURESCALE:
|
||||
|
||||
case SP_LIGHTRADIUS:
|
||||
case SP_LIGHTCOLOUR:
|
||||
case SP_LIGHTPOSITION:
|
||||
|
||||
case SP_FIRSTIMMEDIATE:
|
||||
case SP_CONSTI:
|
||||
case SP_CONSTF:
|
||||
|
@ -1656,18 +1704,33 @@ static void BE_ApplyUniforms(program_t *prog, int permu)
|
|||
}
|
||||
}
|
||||
|
||||
static void BE_RenderMeshProgram(unsigned int vertcount, unsigned int idxfirst, unsigned int idxcount)
|
||||
static void BE_RenderMeshProgram(shader_t *s, unsigned int vertcount, unsigned int idxfirst, unsigned int idxcount)
|
||||
{
|
||||
int vdec = D3D_VDEC_ST0;
|
||||
int vdec = D3D_VDEC_ST0|D3D_VDEC_NORM;
|
||||
int passno;
|
||||
shader_t *s = shaderstate.curshader;
|
||||
//shaderpass_t *pass = s->passes; //unused variable
|
||||
int perm = 0;
|
||||
|
||||
D3DBE_ApplyShaderBits(shaderstate.curshader->passes->shaderbits);
|
||||
program_t *p = s->prog;
|
||||
|
||||
BE_ApplyUniforms(s->prog, 0);
|
||||
if (TEXVALID(shaderstate.curtexnums->bump) && p->handle[perm|PERMUTATION_BUMPMAP].hlsl.vert)
|
||||
perm |= PERMUTATION_BUMPMAP;
|
||||
if (TEXVALID(shaderstate.curtexnums->specular) && p->handle[perm|PERMUTATION_SPECULAR].hlsl.vert)
|
||||
perm |= PERMUTATION_SPECULAR;
|
||||
if (TEXVALID(shaderstate.curtexnums->fullbright) && p->handle[perm|PERMUTATION_FULLBRIGHT].hlsl.vert)
|
||||
perm |= PERMUTATION_FULLBRIGHT;
|
||||
if (TEXVALID(shaderstate.curtexnums->loweroverlay) && p->handle[perm|PERMUTATION_LOWER].hlsl.vert)
|
||||
perm |= PERMUTATION_LOWER;
|
||||
if (TEXVALID(shaderstate.curtexnums->upperoverlay) && p->handle[perm|PERMUTATION_UPPER].hlsl.vert)
|
||||
perm |= PERMUTATION_UPPER;
|
||||
if (r_refdef.gfog_rgbd[3] && p->handle[perm|PERMUTATION_FOG].hlsl.vert)
|
||||
perm |= PERMUTATION_FOG;
|
||||
// if (r_glsl_offsetmapping.ival && TEXVALID(shaderstate.curtexnums->bump) && p->handle[perm|PERMUTATION_OFFSET.hlsl.vert)
|
||||
// perm |= PERMUTATION_OFFSET;
|
||||
|
||||
|
||||
BE_ApplyUniforms(p, perm);
|
||||
|
||||
|
||||
D3DBE_ApplyShaderBits(s->passes->shaderbits);
|
||||
|
||||
/*activate tmus*/
|
||||
for (passno = 0; passno < s->numpasses; passno++)
|
||||
|
@ -1766,8 +1829,17 @@ static void BE_RenderMeshProgram(unsigned int vertcount, unsigned int idxfirst,
|
|||
/*normals/tangents/bitangents*/
|
||||
if (vdec & D3D_VDEC_NORM)
|
||||
{
|
||||
if (shaderstate.batchvbo)
|
||||
{
|
||||
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_NORM, shaderstate.batchvbo->normals.d3d.buff, shaderstate.batchvbo->normals.d3d.offs, sizeof(vec3_t)));
|
||||
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_NORMS, shaderstate.batchvbo->svector.d3d.buff, shaderstate.batchvbo->svector.d3d.offs, sizeof(vec3_t)));
|
||||
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_NORMT, shaderstate.batchvbo->tvector.d3d.buff, shaderstate.batchvbo->tvector.d3d.offs, sizeof(vec3_t)));
|
||||
}
|
||||
else
|
||||
{
|
||||
/*FIXME*/
|
||||
vdec &= ~D3D_VDEC_NORM;
|
||||
}
|
||||
}
|
||||
|
||||
/*bone weights+indexes*/
|
||||
|
@ -1790,7 +1862,7 @@ static void BE_RenderMeshProgram(unsigned int vertcount, unsigned int idxfirst,
|
|||
IDirect3DDevice9_SetPixelShader(pD3DDev9, NULL);
|
||||
}
|
||||
|
||||
static void BE_Cull(unsigned int cullflags)
|
||||
void D3DBE_Cull(unsigned int cullflags)
|
||||
{
|
||||
cullflags |= r_refdef.flipcull;
|
||||
if (shaderstate.curcull != cullflags)
|
||||
|
@ -1830,7 +1902,7 @@ static void BE_DrawMeshChain_Internal(void)
|
|||
float pushdepth;
|
||||
// float pushfactor;
|
||||
|
||||
BE_Cull(shaderstate.curshader->flags & (SHADER_CULL_FRONT | SHADER_CULL_BACK));
|
||||
D3DBE_Cull(shaderstate.curshader->flags & (SHADER_CULL_FRONT | SHADER_CULL_BACK));
|
||||
pushdepth = (shaderstate.curshader->polyoffset.factor + ((shaderstate.flags & BEF_PUSHDEPTH)?r_polygonoffset_submodel_factor.value:0))/0xffff;
|
||||
if (pushdepth != shaderstate.depthbias)
|
||||
{
|
||||
|
@ -1906,6 +1978,9 @@ static void BE_DrawMeshChain_Internal(void)
|
|||
|
||||
switch (shaderstate.mode)
|
||||
{
|
||||
case BEM_LIGHT:
|
||||
BE_RenderMeshProgram(shaderstate.shader_rtlight, vertcount, idxfirst, idxcount);
|
||||
break;
|
||||
case BEM_DEPTHONLY:
|
||||
shaderstate.lastpasscount = 0;
|
||||
i = 0;
|
||||
|
@ -1931,7 +2006,7 @@ static void BE_DrawMeshChain_Internal(void)
|
|||
case BEM_STANDARD:
|
||||
if (shaderstate.curshader->prog)
|
||||
{
|
||||
BE_RenderMeshProgram(vertcount, idxfirst, idxcount);
|
||||
BE_RenderMeshProgram(shaderstate.curshader, vertcount, idxfirst, idxcount);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1956,6 +2031,21 @@ static void BE_DrawMeshChain_Internal(void)
|
|||
void D3DBE_SelectMode(backendmode_t mode)
|
||||
{
|
||||
shaderstate.mode = mode;
|
||||
|
||||
if (mode == BEM_STENCIL)
|
||||
D3DBE_ApplyShaderBits(SBITS_MASK_BITS);
|
||||
}
|
||||
|
||||
void D3DBE_SelectDLight(dlight_t *dl, vec3_t colour)
|
||||
{
|
||||
shaderstate.curdlight = dl;
|
||||
VectorCopy(colour, shaderstate.curdlight_colours);
|
||||
}
|
||||
|
||||
void D3DBE_SelectEntity(entity_t *ent)
|
||||
{
|
||||
shaderstate.curentity = ent;
|
||||
BE_RotateForEntity(ent, ent->model);
|
||||
}
|
||||
|
||||
/*Generates an optimised vbo for each of the given model's textures*/
|
||||
|
@ -2719,12 +2809,12 @@ static void BE_SubmitMeshesPortals(batch_t **worldlist, batch_t *dynamiclist)
|
|||
}
|
||||
}
|
||||
|
||||
void D3DBE_SubmitMeshes (qboolean drawworld, batch_t **blist)
|
||||
void D3DBE_SubmitMeshes (qboolean drawworld, batch_t **blist, int first, int stop)
|
||||
{
|
||||
model_t *model = cl.worldmodel;
|
||||
int i;
|
||||
|
||||
for (i = SHADER_SORT_PORTAL; i < SHADER_SORT_COUNT; i++)
|
||||
for (i = first; i < stop; i++)
|
||||
{
|
||||
if (drawworld)
|
||||
{
|
||||
|
@ -2737,6 +2827,30 @@ void D3DBE_SubmitMeshes (qboolean drawworld, batch_t **blist)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef RTLIGHTS
|
||||
void BE_BaseEntTextures(void)
|
||||
{
|
||||
batch_t *batches[SHADER_SORT_COUNT];
|
||||
BE_GenModelBatches(batches);
|
||||
D3DBE_SubmitMeshes(false, batches, SHADER_SORT_PORTAL, SHADER_SORT_DECAL);
|
||||
BE_SelectEntity(&r_worldentity);
|
||||
}
|
||||
|
||||
void D3DBE_RenderShadowBuffer(unsigned int numverts, IDirect3DVertexBuffer9 *vbuf, unsigned int numindicies, IDirect3DIndexBuffer9 *ibuf)
|
||||
{
|
||||
IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_VERT, vbuf, 0, sizeof(vecV_t));
|
||||
IDirect3DDevice9_SetIndices(pD3DDev9, ibuf);
|
||||
|
||||
if (0 != shaderstate.curvertdecl)
|
||||
{
|
||||
shaderstate.curvertdecl = 0;
|
||||
d3dcheck(IDirect3DDevice9_SetVertexDeclaration(pD3DDev9, vertexdecls[shaderstate.curvertdecl]));
|
||||
}
|
||||
|
||||
IDirect3DDevice9_DrawIndexedPrimitive(pD3DDev9, D3DPT_TRIANGLELIST, 0, 0, numverts, 0, numindicies/3);
|
||||
}
|
||||
#endif
|
||||
|
||||
void D3DBE_DrawWorld (qbyte *vis)
|
||||
{
|
||||
batch_t *batches[SHADER_SORT_COUNT];
|
||||
|
@ -2774,13 +2888,22 @@ void D3DBE_DrawWorld (qbyte *vis)
|
|||
BE_SelectMode(BEM_STANDARD);
|
||||
|
||||
RSpeedRemark();
|
||||
D3DBE_SubmitMeshes(true, batches);
|
||||
D3DBE_SubmitMeshes(true, batches, SHADER_SORT_PORTAL, SHADER_SORT_DECAL);
|
||||
RSpeedEnd(RSPEED_WORLD);
|
||||
|
||||
#ifdef RTLIGHTS
|
||||
RSpeedRemark();
|
||||
D3DBE_SelectEntity(&r_worldentity);
|
||||
Sh_DrawLights(vis, batches);
|
||||
RSpeedEnd(RSPEED_STENCILSHADOWS);
|
||||
#endif
|
||||
|
||||
D3DBE_SubmitMeshes(true, batches, SHADER_SORT_DECAL, SHADER_SORT_COUNT);
|
||||
}
|
||||
else
|
||||
{
|
||||
RSpeedRemark();
|
||||
D3DBE_SubmitMeshes(false, batches);
|
||||
D3DBE_SubmitMeshes(false, batches, SHADER_SORT_PORTAL, SHADER_SORT_COUNT);
|
||||
RSpeedEnd(RSPEED_DRAWENTITIES);
|
||||
}
|
||||
|
||||
|
|
|
@ -472,7 +472,7 @@ static qboolean initD3D9Device(HWND hWnd, rendererstate_t *info, unsigned int de
|
|||
d3dpp.Windowed = !info->fullscreen;
|
||||
|
||||
d3dpp.EnableAutoDepthStencil = true;
|
||||
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
|
||||
d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;//D3DFMT_D16;
|
||||
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
|
||||
if (info->fullscreen)
|
||||
{
|
||||
|
@ -755,6 +755,16 @@ static void (D3D9_R_NewMap) (void)
|
|||
Surf_DeInit();
|
||||
Surf_WipeStains();
|
||||
Surf_BuildLightmaps();
|
||||
|
||||
#ifdef RTLIGHTS
|
||||
if (r_shadow_realtime_dlight.ival || r_shadow_realtime_world.ival)
|
||||
{
|
||||
R_LoadRTLights();
|
||||
if (rtlights_first == rtlights_max)
|
||||
R_ImportRTLights(cl.worldmodel->entities);
|
||||
}
|
||||
Sh_PreGenerateLights();
|
||||
#endif
|
||||
}
|
||||
|
||||
extern mleaf_t *r_viewleaf, *r_oldviewleaf;
|
||||
|
@ -1299,8 +1309,8 @@ rendererinfo_t d3drendererinfo =
|
|||
D3DBE_GenBrushModelVBO,
|
||||
D3DBE_ClearVBO,
|
||||
D3DBE_UploadAllLightmaps,
|
||||
NULL,
|
||||
NULL,
|
||||
D3DBE_SelectEntity,
|
||||
D3DBE_SelectDLight,
|
||||
D3DBE_LightCullModel,
|
||||
|
||||
"no more"
|
||||
|
|
|
@ -590,7 +590,7 @@ static texnums_t *GL_ChooseSkin(galiasinfo_t *inf, model_t *model, int surfnum,
|
|||
return texnums;
|
||||
}
|
||||
|
||||
#if defined(RTLIGHTS) && defined(GLQUAKE)
|
||||
#if defined(RTLIGHTS)
|
||||
static int numFacing;
|
||||
static qbyte *triangleFacing;
|
||||
static void R_CalcFacing(mesh_t *mesh, vec3_t lightpos)
|
||||
|
@ -653,6 +653,7 @@ static void R_ProjectShadowVolume(mesh_t *mesh, vec3_t lightpos)
|
|||
|
||||
static void R_DrawShadowVolume(mesh_t *mesh)
|
||||
{
|
||||
#ifdef GLQUAKE
|
||||
int t;
|
||||
vec3_t *proj = ProjectedShadowVerts;
|
||||
vecV_t *verts = mesh->xyz_array;
|
||||
|
@ -708,6 +709,7 @@ static void R_DrawShadowVolume(mesh_t *mesh)
|
|||
}
|
||||
}
|
||||
qglEnd();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1136,8 +1138,8 @@ void RotateLightVector(const vec3_t *axis, const vec3_t origin, const vec3_t lig
|
|||
result[2] = DotProduct (offs, axis[2]);
|
||||
}
|
||||
|
||||
#if defined(RTLIGHTS) && defined(GLQUAKE)
|
||||
void GL_LightMesh (mesh_t *mesh, vec3_t lightpos, vec3_t colours, float radius)
|
||||
#if defined(RTLIGHTS)
|
||||
static void GL_LightMesh (mesh_t *mesh, vec3_t lightpos, vec3_t colours, float radius)
|
||||
{
|
||||
vec3_t dir;
|
||||
int i;
|
||||
|
@ -1202,7 +1204,7 @@ void GL_LightMesh (mesh_t *mesh, vec3_t lightpos, vec3_t colours, float radius)
|
|||
}
|
||||
|
||||
//courtesy of DP
|
||||
void R_BuildBumpVectors(const float *v0, const float *v1, const float *v2, const float *tc0, const float *tc1, const float *tc2, float *svector3f, float *tvector3f, float *normal3f)
|
||||
static void R_BuildBumpVectors(const float *v0, const float *v1, const float *v2, const float *tc0, const float *tc1, const float *tc2, float *svector3f, float *tvector3f, float *normal3f)
|
||||
{
|
||||
float f, tangentcross[3], v10[3], v20[3], tc10[2], tc20[2];
|
||||
// 79 add/sub/negate/multiply (1 cycle), 1 compare (3 cycle?), total cycles not counting load/store/exchange roughly 82 cycles
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
//FIXME: this shouldn't be defined
|
||||
#define FORCESTATE
|
||||
#else
|
||||
#define FORCESTATE
|
||||
//#define FORCESTATE
|
||||
#endif
|
||||
//#define WIREFRAME
|
||||
|
||||
|
@ -18,6 +18,10 @@
|
|||
#include <alloca.h>
|
||||
#endif
|
||||
|
||||
#ifdef FORCESTATE
|
||||
#pragma warningmsg("FORCESTATE is active")
|
||||
#endif
|
||||
|
||||
extern cvar_t gl_overbright;
|
||||
|
||||
static const char LIGHTPASS_SHADER[] = "\
|
||||
|
@ -482,6 +486,19 @@ void GL_SelectProgram(int program)
|
|||
}
|
||||
}
|
||||
|
||||
void GLBE_RenderShadowBuffer(unsigned int numverts, int vbo, vecV_t *verts, unsigned numindicies, int ibo, index_t *indicies)
|
||||
{
|
||||
GL_SelectVBO(vbo);
|
||||
GL_SelectEBO(ibo);
|
||||
qglEnableClientState(GL_VERTEX_ARRAY);
|
||||
//draw cached world shadow mesh
|
||||
qglVertexPointer(3, GL_FLOAT, sizeof(vecV_t), verts);
|
||||
qglDrawRangeElements(GL_TRIANGLES, 0, numverts, numindicies, GL_INDEX_TYPE, indicies);
|
||||
RQuantAdd(RQUANT_SHADOWFACES, numindicies);
|
||||
GL_SelectVBO(0);
|
||||
GL_SelectEBO(0);
|
||||
}
|
||||
|
||||
static void GL_DeSelectProgram(void)
|
||||
{
|
||||
if (shaderstate.currentprogram != 0)
|
||||
|
|
|
@ -159,6 +159,8 @@ bucket_t *gltexturetablebuckets[256];
|
|||
int gl_filter_min = GL_LINEAR_MIPMAP_NEAREST;
|
||||
int gl_filter_max = GL_LINEAR;
|
||||
int gl_filter_max_2d = GL_LINEAR;
|
||||
int gl_mipcap_min = 0;
|
||||
int gl_mipcap_max = 1000;
|
||||
|
||||
typedef struct gltexture_s
|
||||
{
|
||||
|
@ -257,6 +259,31 @@ void GL_Texture_Anisotropic_Filtering_Callback (struct cvar_s *var, char *oldval
|
|||
gl_anisotropy_factor = 0;
|
||||
}
|
||||
|
||||
void GL_Mipcap_Callback (struct cvar_s *var, char *oldvalue)
|
||||
{
|
||||
gltexture_t *glt;
|
||||
char *s = var->string;
|
||||
|
||||
s = COM_Parse(s);
|
||||
gl_mipcap_min = *com_token?atoi(com_token):0;
|
||||
if (gl_mipcap_min > 3) /*cap it to 3, so no 16*16 textures get bugged*/
|
||||
gl_mipcap_min = 3;
|
||||
s = COM_Parse(s);
|
||||
gl_mipcap_max = *com_token?atoi(com_token):1000;
|
||||
if (gl_mipcap_max < gl_mipcap_min)
|
||||
gl_mipcap_max = gl_mipcap_min;
|
||||
|
||||
for (glt=gltextures ; glt ; glt=glt->next)
|
||||
{
|
||||
if (!(glt->flags & IF_NOMIPMAP))
|
||||
if (glt->flags & IF_MIPCAP)
|
||||
{
|
||||
GL_MTBind(0, GL_TEXTURE_2D, glt->texnum);
|
||||
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, gl_mipcap_min);
|
||||
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, gl_mipcap_max);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
===============
|
||||
Draw_TextureMode_f
|
||||
|
@ -1336,6 +1363,13 @@ done:
|
|||
|
||||
if (gl_config.sgis_generate_mipmap && !(flags&IF_NOMIPMAP))
|
||||
qglTexParameteri(targ, GL_GENERATE_MIPMAP_SGIS, GL_FALSE);
|
||||
|
||||
/*apply this flag after, so that we can safely change the base (to avoid drivers just not uploading lower mips)*/
|
||||
if (flags & IF_MIPCAP)
|
||||
{
|
||||
qglTexParameteri(targ, GL_TEXTURE_BASE_LEVEL, gl_mipcap_min);
|
||||
qglTexParameteri(targ, GL_TEXTURE_MAX_LEVEL, gl_mipcap_max);
|
||||
}
|
||||
}
|
||||
|
||||
void GL_Upload32 (char *name, unsigned *data, int width, int height, unsigned int flags)
|
||||
|
|
|
@ -1156,12 +1156,12 @@ TRACE(("dbg: RMod_LoadTextures: inittexturedescs\n"));
|
|||
mipheight = tx->height;
|
||||
}
|
||||
|
||||
tn.base = R_LoadReplacementTexture(mt->name, loadname, IF_NOALPHA|IF_SUBDIRONLY);
|
||||
tn.base = R_LoadReplacementTexture(mt->name, loadname, ((*mt->name == '{')?0:IF_NOALPHA)|IF_SUBDIRONLY|IF_MIPCAP);
|
||||
if (!TEXVALID(tn.base))
|
||||
{
|
||||
tn.base = R_LoadReplacementTexture(mt->name, "bmodels", (*mt->name == '{')?0:IF_NOALPHA);
|
||||
tn.base = R_LoadReplacementTexture(mt->name, "bmodels", ((*mt->name == '{')?0:IF_NOALPHA)|IF_MIPCAP);
|
||||
if (!TEXVALID(tn.base))
|
||||
tn.base = R_LoadTexture8 (mt->name, mipwidth, mipheight, mipbase, (*mt->name == '{')?0:IF_NOALPHA, 1);
|
||||
tn.base = R_LoadTexture8 (mt->name, mipwidth, mipheight, mipbase, ((*mt->name == '{')?0:IF_NOALPHA)|IF_MIPCAP, 1);
|
||||
}
|
||||
|
||||
if (r_fb_bmodels.value)
|
||||
|
@ -1169,12 +1169,12 @@ TRACE(("dbg: RMod_LoadTextures: inittexturedescs\n"));
|
|||
snprintf(altname, sizeof(altname)-1, "%s_luma", mt->name);
|
||||
if (gl_load24bit.value)
|
||||
{
|
||||
tn.fullbright = R_LoadReplacementTexture(altname, loadname, IF_NOGAMMA|IF_SUBDIRONLY);
|
||||
tn.fullbright = R_LoadReplacementTexture(altname, loadname, IF_NOGAMMA|IF_SUBDIRONLY|IF_MIPCAP);
|
||||
if (!TEXVALID(tn.fullbright))
|
||||
tn.fullbright = R_LoadReplacementTexture(altname, "bmodels", IF_NOGAMMA);
|
||||
tn.fullbright = R_LoadReplacementTexture(altname, "bmodels", IF_NOGAMMA|IF_MIPCAP);
|
||||
}
|
||||
if ((*mt->name != '{') && !TEXVALID(tn.fullbright)) //generate one (if possible).
|
||||
tn.fullbright = R_LoadTextureFB(altname, mipwidth, mipheight, mipbase, IF_NOGAMMA);
|
||||
tn.fullbright = R_LoadTextureFB(altname, mipwidth, mipheight, mipbase, IF_NOGAMMA|IF_MIPCAP);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1184,9 +1184,9 @@ TRACE(("dbg: RMod_LoadTextures: inittexturedescs\n"));
|
|||
if (r_loadbumpmapping)
|
||||
{
|
||||
snprintf(altname, sizeof(altname)-1, "%s_norm", mt->name);
|
||||
tn.bump = R_LoadReplacementTexture(altname, loadname, IF_NOGAMMA|IF_SUBDIRONLY);
|
||||
tn.bump = R_LoadReplacementTexture(altname, loadname, IF_NOGAMMA|IF_SUBDIRONLY|IF_MIPCAP);
|
||||
if (!TEXVALID(tn.bump))
|
||||
tn.bump = R_LoadReplacementTexture(altname, "bmodels", IF_NOGAMMA);
|
||||
tn.bump = R_LoadReplacementTexture(altname, "bmodels", IF_NOGAMMA|IF_MIPCAP);
|
||||
}
|
||||
if (!TEXVALID(tn.bump))
|
||||
{
|
||||
|
@ -1215,9 +1215,9 @@ TRACE(("dbg: RMod_LoadTextures: inittexturedescs\n"));
|
|||
if (gl_specular.value && gl_load24bit.value)
|
||||
{
|
||||
snprintf(altname, sizeof(altname)-1, "%s_gloss", mt->name);
|
||||
tn.specular = R_LoadHiResTexture(altname, loadname, IF_NOALPHA|IF_NOGAMMA|IF_SUBDIRONLY);
|
||||
tn.specular = R_LoadHiResTexture(altname, loadname, IF_NOALPHA|IF_NOGAMMA|IF_SUBDIRONLY|IF_MIPCAP);
|
||||
if (!TEXVALID(tn.specular))
|
||||
tn.specular = R_LoadHiResTexture(altname, "bmodels", IF_NOALPHA|IF_NOGAMMA);
|
||||
tn.specular = R_LoadHiResTexture(altname, "bmodels", IF_NOALPHA|IF_NOGAMMA|IF_MIPCAP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1360,12 +1360,12 @@ void RMod_NowLoadExternal(void)
|
|||
tx->alphaed = alphaed;
|
||||
}
|
||||
|
||||
tn.base = R_LoadHiResTexture(tx->name, loadname, IF_NOALPHA);
|
||||
tn.base = R_LoadHiResTexture(tx->name, loadname, IF_NOALPHA|IF_MIPCAP);
|
||||
if (!TEXVALID(tn.base))
|
||||
{
|
||||
tn.base = R_LoadHiResTexture(tx->name, "bmodels", IF_NOALPHA);
|
||||
tn.base = R_LoadHiResTexture(tx->name, "bmodels", IF_NOALPHA|IF_MIPCAP);
|
||||
if (!TEXVALID(tn.base))
|
||||
tn.base = R_LoadReplacementTexture("light1_4", NULL, IF_NOALPHA); //a fallback. :/
|
||||
tn.base = R_LoadReplacementTexture("light1_4", NULL, IF_NOALPHA|IF_MIPCAP); //a fallback. :/
|
||||
}
|
||||
}
|
||||
if (!TEXVALID(tn.bump) && *tx->name != '{' && r_loadbumpmapping)
|
||||
|
|
|
@ -274,18 +274,10 @@ void R_RenderDlights (void)
|
|||
dlight_t *l;
|
||||
vec3_t waste1, waste2;
|
||||
unsigned int beflags = 0;
|
||||
float intensity;
|
||||
|
||||
switch(r_flashblend.ival)
|
||||
{
|
||||
case 0:
|
||||
return;
|
||||
default:
|
||||
case 1:
|
||||
break;
|
||||
case 2:
|
||||
if (r_coronas.value)
|
||||
beflags |= BEF_FORCENODEPTH;
|
||||
break;
|
||||
}
|
||||
|
||||
// r_dlightframecount = r_framecount + 1; // because the count hasn't
|
||||
// advanced yet for this frame
|
||||
|
@ -308,13 +300,23 @@ void R_RenderDlights (void)
|
|||
continue; //was a muzzleflash
|
||||
}
|
||||
|
||||
if (r_flashblend.ival == 2)
|
||||
intensity = l->corona * 0.25;
|
||||
if (r_flashblend.value && (l->flags & LFLAG_FLASHBLEND))
|
||||
intensity = l->corona; /*intensity is already in the corona value...*/
|
||||
else
|
||||
intensity = l->corona * r_coronas.value;
|
||||
if (intensity <= 0)
|
||||
continue;
|
||||
|
||||
/*coronas use depth testing to compute visibility*/
|
||||
if (r_coronas.value)
|
||||
{
|
||||
if (TraceLineN(r_refdef.vieworg, l->origin, waste1, waste2))
|
||||
continue;
|
||||
}
|
||||
if (!R_BuildDlightMesh (l, l->corona, l->coronascale, false))
|
||||
AddLightBlend (l->color[0]*5, l->color[1]*5, l->color[2]*5, l->radius * 0.0003);
|
||||
|
||||
if (!R_BuildDlightMesh (l, intensity, l->coronascale, false) && r_flashblend.value)
|
||||
AddLightBlend (l->color[0], l->color[1], l->color[2], l->radius * 0.0003);
|
||||
else
|
||||
BE_DrawMesh_Single(flashblend_shader, &flashblend_mesh, NULL, &flashblend_shader->defaulttextures, beflags);
|
||||
}
|
||||
|
@ -445,6 +447,457 @@ void R_PushDlights (void)
|
|||
}
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//rtlight loading
|
||||
|
||||
#ifdef RTLIGHTS
|
||||
void R_ImportRTLights(char *entlump)
|
||||
{
|
||||
typedef enum lighttype_e {LIGHTTYPE_MINUSX, LIGHTTYPE_RECIPX, LIGHTTYPE_RECIPXX, LIGHTTYPE_NONE, LIGHTTYPE_SUN, LIGHTTYPE_MINUSXX} lighttype_t;
|
||||
|
||||
/*I'm using the DP code so I know I'll get the DP results*/
|
||||
int entnum, style, islight, skin, pflags, effects, n;
|
||||
lighttype_t type;
|
||||
float origin[3], angles[3], radius, color[3], light[4], fadescale, lightscale, originhack[3], overridecolor[3], vec[4];
|
||||
char key[256], value[8192];
|
||||
int nest;
|
||||
|
||||
COM_Parse(entlump);
|
||||
if (!strcmp(com_token, "Version"))
|
||||
{
|
||||
entlump = COM_Parse(entlump);
|
||||
entlump = COM_Parse(entlump);
|
||||
}
|
||||
|
||||
for (entnum = 0; ;entnum++)
|
||||
{
|
||||
entlump = COM_Parse(entlump);
|
||||
if (com_token[0] != '{')
|
||||
break;
|
||||
|
||||
type = LIGHTTYPE_MINUSX;
|
||||
origin[0] = origin[1] = origin[2] = 0;
|
||||
originhack[0] = originhack[1] = originhack[2] = 0;
|
||||
angles[0] = angles[1] = angles[2] = 0;
|
||||
color[0] = color[1] = color[2] = 1;
|
||||
light[0] = light[1] = light[2] = 1;light[3] = 300;
|
||||
overridecolor[0] = overridecolor[1] = overridecolor[2] = 1;
|
||||
fadescale = 1;
|
||||
lightscale = 1;
|
||||
style = 0;
|
||||
skin = 0;
|
||||
pflags = 0;
|
||||
effects = 0;
|
||||
islight = false;
|
||||
nest = 1;
|
||||
while (1)
|
||||
{
|
||||
entlump = COM_Parse(entlump);
|
||||
if (!entlump)
|
||||
break; // error
|
||||
if (com_token[0] == '{')
|
||||
{
|
||||
nest++;
|
||||
continue;
|
||||
}
|
||||
if (com_token[0] == '}')
|
||||
{
|
||||
nest--;
|
||||
if (!nest)
|
||||
break; // end of entity
|
||||
continue;
|
||||
}
|
||||
if (nest!=1)
|
||||
continue;
|
||||
if (com_token[0] == '_')
|
||||
Q_strncpyz(key, com_token + 1, sizeof(key));
|
||||
else
|
||||
Q_strncpyz(key, com_token, sizeof(key));
|
||||
while (key[strlen(key)-1] == ' ') // remove trailing spaces
|
||||
key[strlen(key)-1] = 0;
|
||||
entlump = COM_Parse(entlump);
|
||||
if (!entlump)
|
||||
break; // error
|
||||
Q_strncpyz(value, com_token, sizeof(value));
|
||||
|
||||
// now that we have the key pair worked out...
|
||||
if (!strcmp("light", key))
|
||||
{
|
||||
n = sscanf(value, "%f %f %f %f", &vec[0], &vec[1], &vec[2], &vec[3]);
|
||||
if (n == 1)
|
||||
{
|
||||
// quake
|
||||
light[0] = vec[0] * (1.0f / 256.0f);
|
||||
light[1] = vec[0] * (1.0f / 256.0f);
|
||||
light[2] = vec[0] * (1.0f / 256.0f);
|
||||
light[3] = vec[0];
|
||||
}
|
||||
else if (n == 4)
|
||||
{
|
||||
// halflife
|
||||
light[0] = vec[0] * (1.0f / 255.0f);
|
||||
light[1] = vec[1] * (1.0f / 255.0f);
|
||||
light[2] = vec[2] * (1.0f / 255.0f);
|
||||
light[3] = vec[3];
|
||||
}
|
||||
}
|
||||
else if (!strcmp("delay", key))
|
||||
type = atoi(value);
|
||||
else if (!strcmp("origin", key))
|
||||
sscanf(value, "%f %f %f", &origin[0], &origin[1], &origin[2]);
|
||||
else if (!strcmp("angle", key))
|
||||
angles[0] = 0, angles[1] = atof(value), angles[2] = 0;
|
||||
else if (!strcmp("angles", key))
|
||||
sscanf(value, "%f %f %f", &angles[0], &angles[1], &angles[2]);
|
||||
else if (!strcmp("color", key))
|
||||
sscanf(value, "%f %f %f", &color[0], &color[1], &color[2]);
|
||||
else if (!strcmp("wait", key))
|
||||
fadescale = atof(value);
|
||||
else if (!strcmp("classname", key))
|
||||
{
|
||||
if (!strncmp(value, "light", 5))
|
||||
{
|
||||
islight = true;
|
||||
if (!strcmp(value, "light_fluoro"))
|
||||
{
|
||||
originhack[0] = 0;
|
||||
originhack[1] = 0;
|
||||
originhack[2] = 0;
|
||||
overridecolor[0] = 1;
|
||||
overridecolor[1] = 1;
|
||||
overridecolor[2] = 1;
|
||||
}
|
||||
if (!strcmp(value, "light_fluorospark"))
|
||||
{
|
||||
originhack[0] = 0;
|
||||
originhack[1] = 0;
|
||||
originhack[2] = 0;
|
||||
overridecolor[0] = 1;
|
||||
overridecolor[1] = 1;
|
||||
overridecolor[2] = 1;
|
||||
}
|
||||
if (!strcmp(value, "light_globe"))
|
||||
{
|
||||
originhack[0] = 0;
|
||||
originhack[1] = 0;
|
||||
originhack[2] = 0;
|
||||
overridecolor[0] = 1;
|
||||
overridecolor[1] = 0.8;
|
||||
overridecolor[2] = 0.4;
|
||||
}
|
||||
if (!strcmp(value, "light_flame_large_yellow"))
|
||||
{
|
||||
originhack[0] = 0;
|
||||
originhack[1] = 0;
|
||||
originhack[2] = 0;
|
||||
overridecolor[0] = 1;
|
||||
overridecolor[1] = 0.5;
|
||||
overridecolor[2] = 0.1;
|
||||
}
|
||||
if (!strcmp(value, "light_flame_small_yellow"))
|
||||
{
|
||||
originhack[0] = 0;
|
||||
originhack[1] = 0;
|
||||
originhack[2] = 0;
|
||||
overridecolor[0] = 1;
|
||||
overridecolor[1] = 0.5;
|
||||
overridecolor[2] = 0.1;
|
||||
}
|
||||
if (!strcmp(value, "light_torch_small_white"))
|
||||
{
|
||||
originhack[0] = 0;
|
||||
originhack[1] = 0;
|
||||
originhack[2] = 0;
|
||||
overridecolor[0] = 1;
|
||||
overridecolor[1] = 0.5;
|
||||
overridecolor[2] = 0.1;
|
||||
}
|
||||
if (!strcmp(value, "light_torch_small_walltorch"))
|
||||
{
|
||||
originhack[0] = 0;
|
||||
originhack[1] = 0;
|
||||
originhack[2] = 0;
|
||||
overridecolor[0] = 1;
|
||||
overridecolor[1] = 0.5;
|
||||
overridecolor[2] = 0.1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!strcmp("style", key))
|
||||
style = atoi(value);
|
||||
else if (!strcmp("skin", key))
|
||||
skin = (int)atof(value);
|
||||
else if (!strcmp("pflags", key))
|
||||
pflags = (int)atof(value);
|
||||
else if (!strcmp("effects", key))
|
||||
effects = (int)atof(value);
|
||||
|
||||
else if (!strcmp("scale", key))
|
||||
lightscale = atof(value);
|
||||
else if (!strcmp("fade", key))
|
||||
fadescale = atof(value);
|
||||
|
||||
else if (!strcmp("light_radius", key))
|
||||
{
|
||||
light[0] = 1;
|
||||
light[1] = 1;
|
||||
light[2] = 1;
|
||||
light[3] = atof(value);
|
||||
}
|
||||
}
|
||||
if (!islight)
|
||||
continue;
|
||||
if (lightscale <= 0)
|
||||
lightscale = 1;
|
||||
if (fadescale <= 0)
|
||||
fadescale = 1;
|
||||
if (color[0] == color[1] && color[0] == color[2])
|
||||
{
|
||||
color[0] *= overridecolor[0];
|
||||
color[1] *= overridecolor[1];
|
||||
color[2] *= overridecolor[2];
|
||||
}
|
||||
radius = light[3] * 1/*r_editlights_quakelightsizescale*/ * lightscale / fadescale;
|
||||
color[0] = color[0] * light[0];
|
||||
color[1] = color[1] * light[1];
|
||||
color[2] = color[2] * light[2];
|
||||
switch (type)
|
||||
{
|
||||
case LIGHTTYPE_MINUSX:
|
||||
break;
|
||||
case LIGHTTYPE_RECIPX:
|
||||
radius *= 2;
|
||||
VectorScale(color, (1.0f / 16.0f), color);
|
||||
break;
|
||||
case LIGHTTYPE_RECIPXX:
|
||||
radius *= 2;
|
||||
VectorScale(color, (1.0f / 16.0f), color);
|
||||
break;
|
||||
default:
|
||||
case LIGHTTYPE_NONE:
|
||||
break;
|
||||
case LIGHTTYPE_SUN:
|
||||
break;
|
||||
case LIGHTTYPE_MINUSXX:
|
||||
break;
|
||||
}
|
||||
VectorAdd(origin, originhack, origin);
|
||||
if (radius >= 1)
|
||||
{
|
||||
dlight_t *dl = CL_AllocSlight();
|
||||
if (!dl)
|
||||
break;
|
||||
VectorCopy(origin, dl->origin);
|
||||
AngleVectors(angles, dl->axis[0], dl->axis[1], dl->axis[2]);
|
||||
dl->radius = radius;
|
||||
VectorCopy(color, dl->color);
|
||||
dl->flags = 0;
|
||||
dl->flags |= LFLAG_REALTIMEMODE;
|
||||
dl->flags |= (pflags & PFLAGS_CORONA)?LFLAG_FLASHBLEND:0;
|
||||
dl->flags |= (pflags & PFLAGS_NOSHADOW)?LFLAG_NOSHADOWS:0;
|
||||
dl->style = style+1;
|
||||
|
||||
//FIXME: cubemaps if skin >= 16
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void R_LoadRTLights(void)
|
||||
{
|
||||
dlight_t *dl;
|
||||
char fname[MAX_QPATH];
|
||||
char cubename[MAX_QPATH];
|
||||
char *file;
|
||||
char *end;
|
||||
int style;
|
||||
|
||||
vec3_t org;
|
||||
float radius;
|
||||
vec3_t rgb;
|
||||
unsigned int flags;
|
||||
|
||||
float coronascale;
|
||||
float corona;
|
||||
float ambientscale, diffusescale, specularscale;
|
||||
vec3_t angles;
|
||||
|
||||
//delete all old lights, even dynamic ones
|
||||
rtlights_first = RTL_FIRST;
|
||||
rtlights_max = RTL_FIRST;
|
||||
|
||||
COM_StripExtension(cl.worldmodel->name, fname, sizeof(fname));
|
||||
strncat(fname, ".rtlights", MAX_QPATH-1);
|
||||
|
||||
file = COM_LoadTempFile(fname);
|
||||
if (file)
|
||||
while(1)
|
||||
{
|
||||
end = strchr(file, '\n');
|
||||
if (!end)
|
||||
end = file + strlen(file);
|
||||
if (end == file)
|
||||
break;
|
||||
*end = '\0';
|
||||
|
||||
while(*file == ' ' || *file == '\t')
|
||||
file++;
|
||||
if (*file == '!')
|
||||
{
|
||||
flags = LFLAG_NOSHADOWS;
|
||||
file++;
|
||||
}
|
||||
else
|
||||
flags = 0;
|
||||
|
||||
file = COM_Parse(file);
|
||||
org[0] = atof(com_token);
|
||||
file = COM_Parse(file);
|
||||
org[1] = atof(com_token);
|
||||
file = COM_Parse(file);
|
||||
org[2] = atof(com_token);
|
||||
|
||||
file = COM_Parse(file);
|
||||
radius = atof(com_token);
|
||||
|
||||
file = COM_Parse(file);
|
||||
rgb[0] = file?atof(com_token):1;
|
||||
file = COM_Parse(file);
|
||||
rgb[1] = file?atof(com_token):1;
|
||||
file = COM_Parse(file);
|
||||
rgb[2] = file?atof(com_token):1;
|
||||
|
||||
file = COM_Parse(file);
|
||||
style = file?atof(com_token):0;
|
||||
|
||||
file = COM_Parse(file);
|
||||
//cubemap
|
||||
Q_strncpyz(cubename, com_token, sizeof(cubename));
|
||||
|
||||
file = COM_Parse(file);
|
||||
//corona
|
||||
corona = file?atof(com_token):0;
|
||||
|
||||
file = COM_Parse(file);
|
||||
angles[0] = file?atof(com_token):0;
|
||||
file = COM_Parse(file);
|
||||
angles[1] = file?atof(com_token):0;
|
||||
file = COM_Parse(file);
|
||||
angles[2] = file?atof(com_token):0;
|
||||
|
||||
file = COM_Parse(file);
|
||||
//corrona scale
|
||||
coronascale = file?atof(com_token):0.25;
|
||||
|
||||
file = COM_Parse(file);
|
||||
//ambient
|
||||
ambientscale = file?atof(com_token):0;
|
||||
|
||||
file = COM_Parse(file);
|
||||
//diffuse
|
||||
diffusescale = file?atof(com_token):1;
|
||||
|
||||
file = COM_Parse(file);
|
||||
//specular
|
||||
specularscale = file?atof(com_token):1;
|
||||
|
||||
file = COM_Parse(file);
|
||||
flags |= file?atoi(com_token):LFLAG_REALTIMEMODE;
|
||||
|
||||
if (radius)
|
||||
{
|
||||
dl = CL_AllocSlight();
|
||||
if (!dl)
|
||||
break;
|
||||
|
||||
VectorCopy(org, dl->origin);
|
||||
dl->radius = radius;
|
||||
VectorCopy(rgb, dl->color);
|
||||
dl->corona = corona;
|
||||
dl->coronascale = coronascale;
|
||||
dl->die = 0;
|
||||
dl->flags = flags;
|
||||
AngleVectors(angles, dl->axis[0], dl->axis[1], dl->axis[2]);
|
||||
|
||||
Q_strncpyz(dl->cubemapname, cubename, sizeof(dl->cubemapname));
|
||||
if (*dl->cubemapname)
|
||||
dl->cubetexture = R_LoadReplacementTexture(dl->cubemapname, "", IF_CUBEMAP);
|
||||
else
|
||||
dl->cubetexture = r_nulltex;
|
||||
|
||||
dl->style = style+1;
|
||||
}
|
||||
file = end+1;
|
||||
}
|
||||
}
|
||||
|
||||
void R_SaveRTLights_f(void)
|
||||
{
|
||||
dlight_t *light;
|
||||
vfsfile_t *f;
|
||||
unsigned int i;
|
||||
char fname[MAX_QPATH];
|
||||
vec3_t ang;
|
||||
COM_StripExtension(cl.worldmodel->name, fname, sizeof(fname));
|
||||
strncat(fname, ".rtlights", MAX_QPATH-1);
|
||||
|
||||
FS_CreatePath(fname, FS_GAMEONLY);
|
||||
f = FS_OpenVFS(fname, "wb", FS_GAMEONLY);
|
||||
if (!f)
|
||||
{
|
||||
Con_Printf("couldn't open %s\n", fname);
|
||||
return;
|
||||
}
|
||||
for (light = cl_dlights+rtlights_first, i=rtlights_first; i<rtlights_max; i++, light++)
|
||||
{
|
||||
if (light->die)
|
||||
continue;
|
||||
if (!light->radius)
|
||||
continue;
|
||||
VectorAngles(light->axis[0], light->axis[2], ang);
|
||||
VFS_PUTS(f, va(
|
||||
"%s%f %f %f "
|
||||
"%f %f %f %f "
|
||||
"%i "
|
||||
"\"%s\" %f "
|
||||
"%f %f %f "
|
||||
"%f %f %f %f %i "
|
||||
"\n"
|
||||
,
|
||||
(light->flags & LFLAG_NOSHADOWS)?"!":"", light->origin[0], light->origin[1], light->origin[2],
|
||||
light->radius, light->color[0], light->color[1], light->color[2],
|
||||
light->style-1,
|
||||
light->cubemapname, light->corona,
|
||||
ang[0], ang[1], ang[2],
|
||||
light->coronascale, light->ambientscale, light->diffusescale, light->specularscale, light->flags&(LFLAG_NORMALMODE|LFLAG_REALTIMEMODE|LFLAG_CREPUSCULAR)
|
||||
));
|
||||
}
|
||||
VFS_CLOSE(f);
|
||||
Con_Printf("rtlights saved to %s\n", fname);
|
||||
}
|
||||
|
||||
void R_ReloadRTLights_f(void)
|
||||
{
|
||||
if (!cl.worldmodel)
|
||||
{
|
||||
Con_Printf("Cannot reload lights at this time\n");
|
||||
return;
|
||||
}
|
||||
rtlights_first = RTL_FIRST;
|
||||
rtlights_max = RTL_FIRST;
|
||||
if (!strcmp(Cmd_Argv(1), "bsp"))
|
||||
R_ImportRTLights(cl.worldmodel->entities);
|
||||
else if (!strcmp(Cmd_Argv(1), "rtlights"))
|
||||
R_LoadRTLights();
|
||||
else if (strcmp(Cmd_Argv(1), "none"))
|
||||
{
|
||||
R_LoadRTLights();
|
||||
if (rtlights_first == rtlights_max)
|
||||
R_ImportRTLights(cl.worldmodel->entities);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
=============================================================================
|
||||
|
||||
|
|
|
@ -24,9 +24,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include "glquake.h"
|
||||
#include "gl_draw.h"
|
||||
|
||||
static void R_ReloadRTLights_f(void);
|
||||
static void R_SaveRTLights_f(void);
|
||||
|
||||
/*
|
||||
==================
|
||||
R_InitTextures
|
||||
|
@ -446,8 +443,6 @@ void GLV_Gamma_Callback(struct cvar_s *var, char *oldvalue);
|
|||
void GLR_DeInit (void)
|
||||
{
|
||||
Cmd_RemoveCommand ("timerefresh");
|
||||
Cmd_RemoveCommand ("r_editlights_reload");
|
||||
Cmd_RemoveCommand ("r_editlights_save");
|
||||
|
||||
Cmd_RemoveCommand ("makewad");
|
||||
|
||||
|
@ -472,10 +467,6 @@ void GLR_DeInit (void)
|
|||
void GLR_Init (void)
|
||||
{
|
||||
Cmd_AddRemCommand ("timerefresh", GLR_TimeRefresh_f);
|
||||
#ifdef RTLIGHTS
|
||||
Cmd_AddRemCommand ("r_editlights_reload", R_ReloadRTLights_f);
|
||||
Cmd_AddRemCommand ("r_editlights_save", R_SaveRTLights_f);
|
||||
#endif
|
||||
|
||||
// Cmd_AddRemCommand ("makewad", R_MakeTexWad_f);
|
||||
|
||||
|
@ -491,453 +482,6 @@ void GLR_Init (void)
|
|||
GLR_ReInit();
|
||||
}
|
||||
|
||||
#ifdef RTLIGHTS
|
||||
static void R_ImportRTLights(char *entlump)
|
||||
{
|
||||
typedef enum lighttype_e {LIGHTTYPE_MINUSX, LIGHTTYPE_RECIPX, LIGHTTYPE_RECIPXX, LIGHTTYPE_NONE, LIGHTTYPE_SUN, LIGHTTYPE_MINUSXX} lighttype_t;
|
||||
|
||||
/*I'm using the DP code so I know I'll get the DP results*/
|
||||
int entnum, style, islight, skin, pflags, effects, n;
|
||||
lighttype_t type;
|
||||
float origin[3], angles[3], radius, color[3], light[4], fadescale, lightscale, originhack[3], overridecolor[3], vec[4];
|
||||
char key[256], value[8192];
|
||||
int nest;
|
||||
|
||||
COM_Parse(entlump);
|
||||
if (!strcmp(com_token, "Version"))
|
||||
{
|
||||
entlump = COM_Parse(entlump);
|
||||
entlump = COM_Parse(entlump);
|
||||
}
|
||||
|
||||
for (entnum = 0; ;entnum++)
|
||||
{
|
||||
entlump = COM_Parse(entlump);
|
||||
if (com_token[0] != '{')
|
||||
break;
|
||||
|
||||
type = LIGHTTYPE_MINUSX;
|
||||
origin[0] = origin[1] = origin[2] = 0;
|
||||
originhack[0] = originhack[1] = originhack[2] = 0;
|
||||
angles[0] = angles[1] = angles[2] = 0;
|
||||
color[0] = color[1] = color[2] = 1;
|
||||
light[0] = light[1] = light[2] = 1;light[3] = 300;
|
||||
overridecolor[0] = overridecolor[1] = overridecolor[2] = 1;
|
||||
fadescale = 1;
|
||||
lightscale = 1;
|
||||
style = 0;
|
||||
skin = 0;
|
||||
pflags = 0;
|
||||
effects = 0;
|
||||
islight = false;
|
||||
nest = 1;
|
||||
while (1)
|
||||
{
|
||||
entlump = COM_Parse(entlump);
|
||||
if (!entlump)
|
||||
break; // error
|
||||
if (com_token[0] == '{')
|
||||
{
|
||||
nest++;
|
||||
continue;
|
||||
}
|
||||
if (com_token[0] == '}')
|
||||
{
|
||||
nest--;
|
||||
if (!nest)
|
||||
break; // end of entity
|
||||
continue;
|
||||
}
|
||||
if (nest!=1)
|
||||
continue;
|
||||
if (com_token[0] == '_')
|
||||
Q_strncpyz(key, com_token + 1, sizeof(key));
|
||||
else
|
||||
Q_strncpyz(key, com_token, sizeof(key));
|
||||
while (key[strlen(key)-1] == ' ') // remove trailing spaces
|
||||
key[strlen(key)-1] = 0;
|
||||
entlump = COM_Parse(entlump);
|
||||
if (!entlump)
|
||||
break; // error
|
||||
Q_strncpyz(value, com_token, sizeof(value));
|
||||
|
||||
// now that we have the key pair worked out...
|
||||
if (!strcmp("light", key))
|
||||
{
|
||||
n = sscanf(value, "%f %f %f %f", &vec[0], &vec[1], &vec[2], &vec[3]);
|
||||
if (n == 1)
|
||||
{
|
||||
// quake
|
||||
light[0] = vec[0] * (1.0f / 256.0f);
|
||||
light[1] = vec[0] * (1.0f / 256.0f);
|
||||
light[2] = vec[0] * (1.0f / 256.0f);
|
||||
light[3] = vec[0];
|
||||
}
|
||||
else if (n == 4)
|
||||
{
|
||||
// halflife
|
||||
light[0] = vec[0] * (1.0f / 255.0f);
|
||||
light[1] = vec[1] * (1.0f / 255.0f);
|
||||
light[2] = vec[2] * (1.0f / 255.0f);
|
||||
light[3] = vec[3];
|
||||
}
|
||||
}
|
||||
else if (!strcmp("delay", key))
|
||||
type = atoi(value);
|
||||
else if (!strcmp("origin", key))
|
||||
sscanf(value, "%f %f %f", &origin[0], &origin[1], &origin[2]);
|
||||
else if (!strcmp("angle", key))
|
||||
angles[0] = 0, angles[1] = atof(value), angles[2] = 0;
|
||||
else if (!strcmp("angles", key))
|
||||
sscanf(value, "%f %f %f", &angles[0], &angles[1], &angles[2]);
|
||||
else if (!strcmp("color", key))
|
||||
sscanf(value, "%f %f %f", &color[0], &color[1], &color[2]);
|
||||
else if (!strcmp("wait", key))
|
||||
fadescale = atof(value);
|
||||
else if (!strcmp("classname", key))
|
||||
{
|
||||
if (!strncmp(value, "light", 5))
|
||||
{
|
||||
islight = true;
|
||||
if (!strcmp(value, "light_fluoro"))
|
||||
{
|
||||
originhack[0] = 0;
|
||||
originhack[1] = 0;
|
||||
originhack[2] = 0;
|
||||
overridecolor[0] = 1;
|
||||
overridecolor[1] = 1;
|
||||
overridecolor[2] = 1;
|
||||
}
|
||||
if (!strcmp(value, "light_fluorospark"))
|
||||
{
|
||||
originhack[0] = 0;
|
||||
originhack[1] = 0;
|
||||
originhack[2] = 0;
|
||||
overridecolor[0] = 1;
|
||||
overridecolor[1] = 1;
|
||||
overridecolor[2] = 1;
|
||||
}
|
||||
if (!strcmp(value, "light_globe"))
|
||||
{
|
||||
originhack[0] = 0;
|
||||
originhack[1] = 0;
|
||||
originhack[2] = 0;
|
||||
overridecolor[0] = 1;
|
||||
overridecolor[1] = 0.8;
|
||||
overridecolor[2] = 0.4;
|
||||
}
|
||||
if (!strcmp(value, "light_flame_large_yellow"))
|
||||
{
|
||||
originhack[0] = 0;
|
||||
originhack[1] = 0;
|
||||
originhack[2] = 0;
|
||||
overridecolor[0] = 1;
|
||||
overridecolor[1] = 0.5;
|
||||
overridecolor[2] = 0.1;
|
||||
}
|
||||
if (!strcmp(value, "light_flame_small_yellow"))
|
||||
{
|
||||
originhack[0] = 0;
|
||||
originhack[1] = 0;
|
||||
originhack[2] = 0;
|
||||
overridecolor[0] = 1;
|
||||
overridecolor[1] = 0.5;
|
||||
overridecolor[2] = 0.1;
|
||||
}
|
||||
if (!strcmp(value, "light_torch_small_white"))
|
||||
{
|
||||
originhack[0] = 0;
|
||||
originhack[1] = 0;
|
||||
originhack[2] = 0;
|
||||
overridecolor[0] = 1;
|
||||
overridecolor[1] = 0.5;
|
||||
overridecolor[2] = 0.1;
|
||||
}
|
||||
if (!strcmp(value, "light_torch_small_walltorch"))
|
||||
{
|
||||
originhack[0] = 0;
|
||||
originhack[1] = 0;
|
||||
originhack[2] = 0;
|
||||
overridecolor[0] = 1;
|
||||
overridecolor[1] = 0.5;
|
||||
overridecolor[2] = 0.1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!strcmp("style", key))
|
||||
style = atoi(value);
|
||||
else if (!strcmp("skin", key))
|
||||
skin = (int)atof(value);
|
||||
else if (!strcmp("pflags", key))
|
||||
pflags = (int)atof(value);
|
||||
else if (!strcmp("effects", key))
|
||||
effects = (int)atof(value);
|
||||
|
||||
else if (!strcmp("scale", key))
|
||||
lightscale = atof(value);
|
||||
else if (!strcmp("fade", key))
|
||||
fadescale = atof(value);
|
||||
|
||||
else if (!strcmp("light_radius", key))
|
||||
{
|
||||
light[0] = 1;
|
||||
light[1] = 1;
|
||||
light[2] = 1;
|
||||
light[3] = atof(value);
|
||||
}
|
||||
}
|
||||
if (!islight)
|
||||
continue;
|
||||
if (lightscale <= 0)
|
||||
lightscale = 1;
|
||||
if (fadescale <= 0)
|
||||
fadescale = 1;
|
||||
if (color[0] == color[1] && color[0] == color[2])
|
||||
{
|
||||
color[0] *= overridecolor[0];
|
||||
color[1] *= overridecolor[1];
|
||||
color[2] *= overridecolor[2];
|
||||
}
|
||||
radius = light[3] * 1/*r_editlights_quakelightsizescale*/ * lightscale / fadescale;
|
||||
color[0] = color[0] * light[0];
|
||||
color[1] = color[1] * light[1];
|
||||
color[2] = color[2] * light[2];
|
||||
switch (type)
|
||||
{
|
||||
case LIGHTTYPE_MINUSX:
|
||||
break;
|
||||
case LIGHTTYPE_RECIPX:
|
||||
radius *= 2;
|
||||
VectorScale(color, (1.0f / 16.0f), color);
|
||||
break;
|
||||
case LIGHTTYPE_RECIPXX:
|
||||
radius *= 2;
|
||||
VectorScale(color, (1.0f / 16.0f), color);
|
||||
break;
|
||||
default:
|
||||
case LIGHTTYPE_NONE:
|
||||
break;
|
||||
case LIGHTTYPE_SUN:
|
||||
break;
|
||||
case LIGHTTYPE_MINUSXX:
|
||||
break;
|
||||
}
|
||||
VectorAdd(origin, originhack, origin);
|
||||
if (radius >= 1)
|
||||
{
|
||||
dlight_t *dl = CL_AllocSlight();
|
||||
if (!dl)
|
||||
break;
|
||||
VectorCopy(origin, dl->origin);
|
||||
AngleVectors(angles, dl->axis[0], dl->axis[1], dl->axis[2]);
|
||||
dl->radius = radius;
|
||||
VectorCopy(color, dl->color);
|
||||
dl->flags = 0;
|
||||
dl->flags |= LFLAG_REALTIMEMODE;
|
||||
dl->flags |= (pflags & PFLAGS_CORONA)?LFLAG_FLASHBLEND:0;
|
||||
dl->flags |= (pflags & PFLAGS_NOSHADOW)?LFLAG_NOSHADOWS:0;
|
||||
dl->style = style+1;
|
||||
|
||||
//FIXME: cubemaps if skin >= 16
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void R_LoadRTLights(void)
|
||||
{
|
||||
dlight_t *dl;
|
||||
char fname[MAX_QPATH];
|
||||
char cubename[MAX_QPATH];
|
||||
char *file;
|
||||
char *end;
|
||||
int style;
|
||||
|
||||
vec3_t org;
|
||||
float radius;
|
||||
vec3_t rgb;
|
||||
unsigned int flags;
|
||||
|
||||
float coronascale;
|
||||
float corona;
|
||||
float ambientscale, diffusescale, specularscale;
|
||||
vec3_t angles;
|
||||
|
||||
//delete all old lights, even dynamic ones
|
||||
rtlights_first = RTL_FIRST;
|
||||
rtlights_max = RTL_FIRST;
|
||||
|
||||
COM_StripExtension(cl.worldmodel->name, fname, sizeof(fname));
|
||||
strncat(fname, ".rtlights", MAX_QPATH-1);
|
||||
|
||||
file = COM_LoadTempFile(fname);
|
||||
if (file)
|
||||
while(1)
|
||||
{
|
||||
end = strchr(file, '\n');
|
||||
if (!end)
|
||||
end = file + strlen(file);
|
||||
if (end == file)
|
||||
break;
|
||||
*end = '\0';
|
||||
|
||||
while(*file == ' ' || *file == '\t')
|
||||
file++;
|
||||
if (*file == '!')
|
||||
{
|
||||
flags = LFLAG_NOSHADOWS;
|
||||
file++;
|
||||
}
|
||||
else
|
||||
flags = 0;
|
||||
|
||||
file = COM_Parse(file);
|
||||
org[0] = atof(com_token);
|
||||
file = COM_Parse(file);
|
||||
org[1] = atof(com_token);
|
||||
file = COM_Parse(file);
|
||||
org[2] = atof(com_token);
|
||||
|
||||
file = COM_Parse(file);
|
||||
radius = atof(com_token);
|
||||
|
||||
file = COM_Parse(file);
|
||||
rgb[0] = file?atof(com_token):1;
|
||||
file = COM_Parse(file);
|
||||
rgb[1] = file?atof(com_token):1;
|
||||
file = COM_Parse(file);
|
||||
rgb[2] = file?atof(com_token):1;
|
||||
|
||||
file = COM_Parse(file);
|
||||
style = file?atof(com_token):0;
|
||||
|
||||
file = COM_Parse(file);
|
||||
//cubemap
|
||||
Q_strncpyz(cubename, com_token, sizeof(cubename));
|
||||
|
||||
file = COM_Parse(file);
|
||||
//corona
|
||||
corona = file?atof(com_token):0;
|
||||
|
||||
file = COM_Parse(file);
|
||||
angles[0] = file?atof(com_token):0;
|
||||
file = COM_Parse(file);
|
||||
angles[1] = file?atof(com_token):0;
|
||||
file = COM_Parse(file);
|
||||
angles[2] = file?atof(com_token):0;
|
||||
|
||||
file = COM_Parse(file);
|
||||
//corrona scale
|
||||
coronascale = file?atof(com_token):0.25;
|
||||
|
||||
file = COM_Parse(file);
|
||||
//ambient
|
||||
ambientscale = file?atof(com_token):0;
|
||||
|
||||
file = COM_Parse(file);
|
||||
//diffuse
|
||||
diffusescale = file?atof(com_token):1;
|
||||
|
||||
file = COM_Parse(file);
|
||||
//specular
|
||||
specularscale = file?atof(com_token):1;
|
||||
|
||||
file = COM_Parse(file);
|
||||
flags |= file?atoi(com_token):LFLAG_REALTIMEMODE;
|
||||
|
||||
if (radius)
|
||||
{
|
||||
dl = CL_AllocSlight();
|
||||
if (!dl)
|
||||
break;
|
||||
|
||||
VectorCopy(org, dl->origin);
|
||||
dl->radius = radius;
|
||||
VectorCopy(rgb, dl->color);
|
||||
dl->corona = corona;
|
||||
dl->coronascale = coronascale;
|
||||
dl->die = 0;
|
||||
dl->flags = flags;
|
||||
AngleVectors(angles, dl->axis[0], dl->axis[1], dl->axis[2]);
|
||||
|
||||
Q_strncpyz(dl->cubemapname, cubename, sizeof(dl->cubemapname));
|
||||
if (*dl->cubemapname)
|
||||
dl->cubetexture = R_LoadReplacementTexture(dl->cubemapname, "", IF_CUBEMAP);
|
||||
else
|
||||
dl->cubetexture = r_nulltex;
|
||||
|
||||
dl->style = style+1;
|
||||
}
|
||||
file = end+1;
|
||||
}
|
||||
}
|
||||
|
||||
static void R_SaveRTLights_f(void)
|
||||
{
|
||||
dlight_t *light;
|
||||
vfsfile_t *f;
|
||||
unsigned int i;
|
||||
char fname[MAX_QPATH];
|
||||
vec3_t ang;
|
||||
COM_StripExtension(cl.worldmodel->name, fname, sizeof(fname));
|
||||
strncat(fname, ".rtlights", MAX_QPATH-1);
|
||||
|
||||
FS_CreatePath(fname, FS_GAMEONLY);
|
||||
f = FS_OpenVFS(fname, "wb", FS_GAMEONLY);
|
||||
if (!f)
|
||||
{
|
||||
Con_Printf("couldn't open %s\n", fname);
|
||||
return;
|
||||
}
|
||||
for (light = cl_dlights+rtlights_first, i=rtlights_first; i<rtlights_max; i++, light++)
|
||||
{
|
||||
if (light->die)
|
||||
continue;
|
||||
if (!light->radius)
|
||||
continue;
|
||||
VectorAngles(light->axis[0], light->axis[2], ang);
|
||||
VFS_PUTS(f, va(
|
||||
"%s%f %f %f "
|
||||
"%f %f %f %f "
|
||||
"%i "
|
||||
"\"%s\" %f "
|
||||
"%f %f %f "
|
||||
"%f %f %f %f %i "
|
||||
"\n"
|
||||
,
|
||||
(light->flags & LFLAG_NOSHADOWS)?"!":"", light->origin[0], light->origin[1], light->origin[2],
|
||||
light->radius, light->color[0], light->color[1], light->color[2],
|
||||
light->style-1,
|
||||
light->cubemapname, light->corona,
|
||||
ang[0], ang[1], ang[2],
|
||||
light->coronascale, light->ambientscale, light->diffusescale, light->specularscale, light->flags&(LFLAG_NORMALMODE|LFLAG_REALTIMEMODE|LFLAG_CREPUSCULAR)
|
||||
));
|
||||
}
|
||||
VFS_CLOSE(f);
|
||||
Con_Printf("rtlights saved to %s\n", fname);
|
||||
}
|
||||
|
||||
void R_ReloadRTLights_f(void)
|
||||
{
|
||||
if (!cl.worldmodel)
|
||||
{
|
||||
Con_Printf("Cannot reload lights at this time\n");
|
||||
return;
|
||||
}
|
||||
rtlights_first = RTL_FIRST;
|
||||
rtlights_max = RTL_FIRST;
|
||||
if (!strcmp(Cmd_Argv(1), "bsp"))
|
||||
R_ImportRTLights(cl.worldmodel->entities);
|
||||
else if (!strcmp(Cmd_Argv(1), "rtlights"))
|
||||
R_LoadRTLights();
|
||||
else if (strcmp(Cmd_Argv(1), "none"))
|
||||
{
|
||||
R_LoadRTLights();
|
||||
if (rtlights_first == rtlights_max)
|
||||
R_ImportRTLights(cl.worldmodel->entities);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
===============
|
||||
R_NewMap
|
||||
|
|
|
@ -949,7 +949,7 @@ static void Shader_LoadPermutations(char *name, program_t *prog, char *script, i
|
|||
typedef struct sgeneric_s
|
||||
{
|
||||
struct sgeneric_s *next;
|
||||
char name[MAX_QPATH];
|
||||
char *name;
|
||||
qboolean failed;
|
||||
program_t prog;
|
||||
} sgeneric_t;
|
||||
|
@ -2047,11 +2047,8 @@ struct sbuiltin_s
|
|||
"#endif\n"
|
||||
|
||||
|
||||
"#ifdef BUMP\n"
|
||||
"vec3 bases = vec3(texture2D(s_t0, tcbase));\n"
|
||||
"#else\n"
|
||||
"vec3 diff = vec3(texture2D(s_t0, tcbase));\n"
|
||||
"#endif\n"
|
||||
|
||||
"#if defined(BUMP) || defined(SPECULAR)\n"
|
||||
"vec3 bumps = vec3(texture2D(s_t1, tcbase)) * 2.0 - 1.0;\n"
|
||||
"#endif\n"
|
||||
|
@ -2062,9 +2059,11 @@ struct sbuiltin_s
|
|||
"vec3 nl = normalize(lightvector);\n"
|
||||
"float colorscale = max(1.0 - dot(lightvector, lightvector)/(l_lightradius*l_lightradius), 0.0);\n"
|
||||
|
||||
"#ifdef BUMP\n"
|
||||
"vec3 diff;\n"
|
||||
"#ifdef BUMP\n"
|
||||
"diff = bases * max(dot(bumps, nl), 0.0);\n"
|
||||
"#else\n"
|
||||
"diff = bases * max(dot(vec3(0.0, 0.0, 1.0), nl), 0.0);\n"
|
||||
"#endif\n"
|
||||
"#ifdef SPECULAR\n"
|
||||
"vec3 halfdir = (normalize(eyevector) + normalize(lightvector))/2.0;\n"
|
||||
|
@ -2110,6 +2109,68 @@ struct sbuiltin_s
|
|||
|
||||
#endif
|
||||
#ifdef D3DQUAKE
|
||||
{QR_DIRECT3D, 9, "rtlight",
|
||||
/*
|
||||
texture units:
|
||||
s0=diffuse, s1=normal, s2=specular, s3=shadowmap
|
||||
custom modifiers:
|
||||
PCF(shadowmap)
|
||||
CUBE(projected cubemap)
|
||||
*/
|
||||
"!!permu BUMP\n"
|
||||
"!!permu SPECULAR\n"
|
||||
"!!permu OFFSETMAPPING\n"
|
||||
"!!permu SKELETAL\n"
|
||||
"!!permu FOG\n"
|
||||
|
||||
|
||||
"struct a2v {\n"
|
||||
"float4 pos: POSITION;\n"
|
||||
"float3 tc: TEXCOORD0;\n"
|
||||
"float3 n: NORMAL0;\n"
|
||||
"float3 s: TANGENT0;\n"
|
||||
"float3 t: BINORMAL0;\n"
|
||||
"};\n"
|
||||
"struct v2f {\n"
|
||||
"#ifndef FRAGMENT_SHADER\n"
|
||||
"float4 pos: POSITION;\n"
|
||||
"#endif\n"
|
||||
"float3 tc: TEXCOORD0;\n"
|
||||
"float3 lpos: TEXCOORD1;\n"
|
||||
"};\n"
|
||||
|
||||
"#ifdef VERTEX_SHADER\n"
|
||||
"float4x4 m_modelviewprojection;\n"
|
||||
"float3 l_lightposition;\n"
|
||||
"v2f main (a2v inp)\n"
|
||||
"{\n"
|
||||
" v2f outp;\n"
|
||||
" outp.pos = mul(m_modelviewprojection, inp.pos);\n"
|
||||
" outp.tc = inp.tc;\n"
|
||||
|
||||
"float3 lightminusvertex = l_lightposition - inp.pos.xyz;\n"
|
||||
"outp.lpos.x = dot(lightminusvertex, inp.s.xyz);\n"
|
||||
"outp.lpos.y = dot(lightminusvertex, inp.t.xyz);\n"
|
||||
"outp.lpos.z = dot(lightminusvertex, inp.n.xyz);\n"
|
||||
" return outp;\n"
|
||||
"}\n"
|
||||
"#endif\n"
|
||||
|
||||
"#ifdef FRAGMENT_SHADER\n"
|
||||
"sampler s_t0;\n"
|
||||
"sampler s_t1;\n"
|
||||
"float l_lightradius;\n"
|
||||
"float3 l_lightcolour;\n"
|
||||
"float4 main (v2f inp) : COLOR0\n"
|
||||
"{\n"
|
||||
" float3 col = l_lightcolour;\n"
|
||||
" col *= max(1.0 - dot(inp.lpos, inp.lpos)/(l_lightradius*l_lightradius), 0.0);\n"
|
||||
" float3 diff = tex2D(s_t0, inp.tc);\n"
|
||||
" return float4(diff * col, 1);"
|
||||
"}\n"
|
||||
"#endif\n"
|
||||
},
|
||||
|
||||
{QR_DIRECT3D, 9, "defaultsky",
|
||||
|
||||
"struct a2v {\n"
|
||||
|
@ -2136,8 +2197,14 @@ struct sbuiltin_s
|
|||
"#ifdef FRAGMENT_SHADER\n"
|
||||
"float e_time;\n"
|
||||
"float3 e_eyepos;\n"
|
||||
"sampler s_t0;\n"
|
||||
"sampler s_t1;\n"
|
||||
|
||||
"float l_lightradius;\n"
|
||||
"float3 l_lightcolour;\n"
|
||||
"float3 l_lightposition;\n"
|
||||
|
||||
"sampler s_t0;\n" /*diffuse*/
|
||||
"sampler s_t1;\n" /*normal*/
|
||||
"sampler s_t2;\n" /*specular*/
|
||||
"float4 main (v2f inp) : COLOR0\n"
|
||||
"{\n"
|
||||
" float2 tccoord;\n"
|
||||
|
@ -2154,7 +2221,6 @@ struct sbuiltin_s
|
|||
" float4 clouds = tex2D(s_t1, tccoord);\n"
|
||||
|
||||
" return float4((solid.rgb*(1.0-clouds.a)) + (clouds.a*clouds.rgb), 1);\n"
|
||||
// " return float4(solid.rgb, 1);"///*gl_FragColor.g = clouds.r;*/gl_FragColor.b = clouds.a;\n"
|
||||
"}\n"
|
||||
"#endif\n"
|
||||
},
|
||||
|
@ -2200,8 +2266,7 @@ struct sbuiltin_s
|
|||
#endif
|
||||
{QR_NONE}
|
||||
};
|
||||
static sgeneric_t *sgenerics;
|
||||
void Shader_UnloadGeneric(program_t *prog)
|
||||
void Shader_UnloadProg(program_t *prog)
|
||||
{
|
||||
if (prog->refs == 1)
|
||||
{
|
||||
|
@ -2241,7 +2306,10 @@ static void Shader_FlushGenerics(void)
|
|||
sgenerics = g->next;
|
||||
|
||||
if (g->prog.refs == 1)
|
||||
{
|
||||
g->prog.refs--;
|
||||
free(g);
|
||||
}
|
||||
else
|
||||
Con_Printf("generic shader still used\n");
|
||||
}
|
||||
|
@ -2263,10 +2331,9 @@ static program_t *Shader_LoadGeneric(char *name, int qrtype)
|
|||
}
|
||||
}
|
||||
|
||||
if (strlen(name) >= sizeof(g->name))
|
||||
return NULL; /*name overflow*/
|
||||
g = malloc(sizeof(*g));
|
||||
g = malloc(sizeof(*g) + strlen(name)+1);
|
||||
memset(g, 0, sizeof(*g));
|
||||
g->name = (char*)(g+1);
|
||||
strcpy(g->name, name);
|
||||
g->next = sgenerics;
|
||||
sgenerics = g;
|
||||
|
@ -2445,6 +2512,11 @@ static void Shader_ProgAutoFields(program_t *prog, char **cvarnames, int *cvarty
|
|||
/*set cvar unirforms*/
|
||||
for (i = 0; cvarnames[i]; i++)
|
||||
{
|
||||
if (prog->numparams == SHADER_PROGPARMS_MAX)
|
||||
{
|
||||
Con_Printf("Too many cvar paramters for program\n");
|
||||
break;
|
||||
}
|
||||
for (p = 0; cvarnames[i][p] && (unsigned char)cvarnames[i][p] > 32 && p < sizeof(tmpname)-1; p++)
|
||||
tmpname[p] = cvarnames[i][p];
|
||||
tmpname[p] = 0;
|
||||
|
@ -2485,15 +2557,26 @@ static void Shader_ProgAutoFields(program_t *prog, char **cvarnames, int *cvarty
|
|||
uniformloc = qglGetAttribLocationARB(prog->handle[p].glsl, shader_field_names[i].name);
|
||||
if (uniformloc != -1)
|
||||
found = true;
|
||||
prog->parm[prog->numparams].handle[p] = uniformloc;
|
||||
if (prog->numparams == SHADER_PROGPARMS_MAX)
|
||||
{
|
||||
if (found)
|
||||
break;
|
||||
}
|
||||
else
|
||||
prog->parm[prog->numparams].handle[p] = uniformloc;
|
||||
}
|
||||
if (found)
|
||||
{
|
||||
prog->parm[prog->numparams].type = shader_field_names[i].ptype;
|
||||
prog->numparams++;
|
||||
if (prog->numparams == SHADER_PROGPARMS_MAX)
|
||||
Con_Printf("Too many paramters for program (ignoring %s)\n", shader_field_names[i].name);
|
||||
else
|
||||
{
|
||||
prog->parm[prog->numparams].type = shader_field_names[i].ptype;
|
||||
prog->numparams++;
|
||||
|
||||
if (shader_field_names[i].ptype < SP_FIRSTUNIFORM)
|
||||
prog->nofixedcompat = true;
|
||||
if (shader_field_names[i].ptype < SP_FIRSTUNIFORM)
|
||||
prog->nofixedcompat = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*set texture uniforms*/
|
||||
|
@ -3663,7 +3746,7 @@ void Shader_Free (shader_t *shader)
|
|||
shader->bucket.data = NULL;
|
||||
|
||||
if (shader->prog)
|
||||
Shader_UnloadGeneric(shader->prog);
|
||||
Shader_UnloadProg(shader->prog);
|
||||
shader->prog = NULL;
|
||||
|
||||
if (shader->skydome)
|
||||
|
|
|
@ -1,11 +1,24 @@
|
|||
#include "quakedef.h"
|
||||
|
||||
#ifdef GLQUAKE
|
||||
#if defined(GLQUAKE) || defined(D3DQUAKE)
|
||||
#ifdef RTLIGHTS
|
||||
|
||||
#include "glquake.h"
|
||||
#include "shader.h"
|
||||
|
||||
#ifdef D3DQUAKE
|
||||
#include "shader.h"
|
||||
#if !defined(HMONITOR_DECLARED) && (WINVER < 0x0500)
|
||||
#define HMONITOR_DECLARED
|
||||
DECLARE_HANDLE(HMONITOR);
|
||||
#endif
|
||||
#include <d3d9.h>
|
||||
extern LPDIRECT3DDEVICE9 pD3DDev9;
|
||||
void D3DBE_Cull(unsigned int sflags);
|
||||
void D3DBE_RenderShadowBuffer(unsigned int numverts, IDirect3DVertexBuffer9 *vbuf, unsigned int numindicies, IDirect3DIndexBuffer9 *ibuf);
|
||||
#endif
|
||||
void GLBE_RenderShadowBuffer(unsigned int numverts, int vbo, vecV_t *verts, unsigned numindicies, int ibo, index_t *indicies);
|
||||
|
||||
#define SHADOWMAP_SIZE 512
|
||||
|
||||
#define PROJECTION_DISTANCE (float)(dl->radius*2)//0x7fffffff
|
||||
|
@ -31,7 +44,21 @@ struct {
|
|||
|
||||
|
||||
|
||||
|
||||
void Sh_Shutdown(void)
|
||||
{
|
||||
#ifdef GLQUAKE
|
||||
if (shadow_fbo_id)
|
||||
{
|
||||
qglDeleteRenderbuffersEXT(1, &shadow_fbo_id);
|
||||
shadow_fbo_id = 0;
|
||||
}
|
||||
if (crepuscular_fbo_id)
|
||||
{
|
||||
qglDeleteRenderbuffersEXT(1, &crepuscular_fbo_id);
|
||||
crepuscular_fbo_id = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -58,7 +85,13 @@ typedef struct shadowmesh_s {
|
|||
unsigned int leafbytes;
|
||||
unsigned char *litleaves;
|
||||
|
||||
#ifdef GLQUAKE
|
||||
GLuint vebo[2];
|
||||
#endif
|
||||
#ifdef D3DQUAKE
|
||||
IDirect3DVertexBuffer9 *d3d_vbuffer;
|
||||
IDirect3DIndexBuffer9 *d3d_ibuffer;
|
||||
#endif
|
||||
} shadowmesh_t;
|
||||
|
||||
/*state of the current shadow mesh*/
|
||||
|
@ -95,7 +128,7 @@ static void SHM_End (void)
|
|||
}
|
||||
sh_vertnum = 0;
|
||||
}
|
||||
static void SHM_Vertex3fv (const GLfloat *v)
|
||||
static void SHM_Vertex3fv (const float *v)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -213,9 +246,26 @@ static void SH_FreeShadowMesh(shadowmesh_t *sm)
|
|||
Z_Free(sm->indicies);
|
||||
Z_Free(sm->verts);
|
||||
|
||||
qglDeleteBuffersARB(2, sm->vebo);
|
||||
sm->vebo[0] = 0;
|
||||
sm->vebo[1] = 0;
|
||||
switch (qrenderer)
|
||||
{
|
||||
#ifdef GLQUAKE
|
||||
case QR_OPENGL:
|
||||
qglDeleteBuffersARB(2, sm->vebo);
|
||||
sm->vebo[0] = 0;
|
||||
sm->vebo[1] = 0;
|
||||
break;
|
||||
#endif
|
||||
#ifdef D3DQUAKE
|
||||
case QR_DIRECT3D:
|
||||
if (sm->d3d_ibuffer)
|
||||
IDirect3DIndexBuffer9_Release(sm->d3d_ibuffer);
|
||||
sm->d3d_ibuffer = NULL;
|
||||
if (sm->d3d_vbuffer)
|
||||
IDirect3DVertexBuffer9_Release(sm->d3d_vbuffer);
|
||||
sm->d3d_vbuffer = NULL;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
Z_Free(sm);
|
||||
}
|
||||
|
@ -285,15 +335,42 @@ static struct shadowmesh_s *SHM_FinishShadowMesh(dlight_t *dl)
|
|||
{
|
||||
if (sh_shmesh != &sh_tempshmesh)
|
||||
{
|
||||
qglGenBuffersARB(2, sh_shmesh->vebo);
|
||||
switch (qrenderer)
|
||||
{
|
||||
#ifdef GLQUAKE
|
||||
case QR_OPENGL:
|
||||
qglGenBuffersARB(2, sh_shmesh->vebo);
|
||||
|
||||
GL_SelectVBO(sh_shmesh->vebo[0]);
|
||||
qglBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(*sh_shmesh->verts) * sh_shmesh->numverts, sh_shmesh->verts, GL_STATIC_DRAW_ARB);
|
||||
|
||||
GL_SelectEBO(sh_shmesh->vebo[1]);
|
||||
qglBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, sizeof(*sh_shmesh->indicies) * sh_shmesh->numindicies, sh_shmesh->indicies, GL_STATIC_DRAW_ARB);
|
||||
break;
|
||||
#endif
|
||||
#ifdef D3DQUAKE
|
||||
case QR_DIRECT3D:
|
||||
if (sh_shmesh->numindicies && sh_shmesh->numverts)
|
||||
{
|
||||
void *map;
|
||||
IDirect3DDevice9_CreateIndexBuffer(pD3DDev9, sizeof(index_t) * sh_shmesh->numindicies, 0, D3DFMT_QINDEX, D3DPOOL_MANAGED, &sh_shmesh->d3d_ibuffer, NULL);
|
||||
IDirect3DIndexBuffer9_Lock(sh_shmesh->d3d_ibuffer, 0, sizeof(index_t) * sh_shmesh->numindicies, &map, D3DLOCK_DISCARD);
|
||||
memcpy(map, sh_shmesh->indicies, sizeof(index_t) * sh_shmesh->numindicies);
|
||||
IDirect3DIndexBuffer9_Unlock(sh_shmesh->d3d_ibuffer);
|
||||
|
||||
IDirect3DDevice9_CreateVertexBuffer(pD3DDev9, sizeof(vecV_t) * sh_shmesh->numverts, D3DUSAGE_WRITEONLY, 0, D3DPOOL_MANAGED, &sh_shmesh->d3d_vbuffer, NULL);
|
||||
IDirect3DVertexBuffer9_Lock(sh_shmesh->d3d_vbuffer, 0, sizeof(vecV_t) * sh_shmesh->numverts, &map, D3DLOCK_DISCARD);
|
||||
memcpy(map, sh_shmesh->verts, sizeof(vecV_t) * sh_shmesh->numverts);
|
||||
IDirect3DVertexBuffer9_Unlock(sh_shmesh->d3d_vbuffer);
|
||||
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
GL_SelectVBO(sh_shmesh->vebo[0]);
|
||||
qglBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(*sh_shmesh->verts) * sh_shmesh->numverts, sh_shmesh->verts, GL_STATIC_DRAW_ARB);
|
||||
Z_Free(sh_shmesh->verts);
|
||||
sh_shmesh->verts = NULL;
|
||||
|
||||
GL_SelectEBO(sh_shmesh->vebo[1]);
|
||||
qglBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, sizeof(*sh_shmesh->indicies) * sh_shmesh->numindicies, sh_shmesh->indicies, GL_STATIC_DRAW_ARB);
|
||||
Z_Free(sh_shmesh->indicies);
|
||||
sh_shmesh->indicies = NULL;
|
||||
}
|
||||
|
@ -1279,12 +1356,31 @@ static void Sh_Scissor (srect_t r)
|
|||
}
|
||||
#endif
|
||||
|
||||
qglScissor(r.x, r.y, r.width, r.height);
|
||||
|
||||
if (qglDepthBoundsEXT)
|
||||
switch(qrenderer)
|
||||
{
|
||||
qglDepthBoundsEXT(r.dmin, r.dmax);
|
||||
qglEnable(GL_DEPTH_BOUNDS_TEST_EXT);
|
||||
#ifdef GLQUAKE
|
||||
case QR_OPENGL:
|
||||
qglScissor(r.x, r.y, r.width, r.height);
|
||||
|
||||
if (qglDepthBoundsEXT)
|
||||
{
|
||||
qglDepthBoundsEXT(r.dmin, r.dmax);
|
||||
qglEnable(GL_DEPTH_BOUNDS_TEST_EXT);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef D3DQUAKE
|
||||
case QR_DIRECT3D:
|
||||
{
|
||||
RECT rect;
|
||||
rect.left = r.x;
|
||||
rect.right = r.x + r.width;
|
||||
rect.top = r.y;
|
||||
rect.bottom = r.y + r.height;
|
||||
IDirect3DDevice9_SetScissorRect(pD3DDev9, &rect);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1656,7 +1752,7 @@ static qboolean Sh_ScissorForBox(vec3_t mins, vec3_t maxs, vrect_t *r)
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef GLQUAKE
|
||||
void GL_BeginRenderBuffer_DepthOnly(texid_t depthtexture)
|
||||
{
|
||||
if (gl_config.ext_framebuffer_objects)
|
||||
|
@ -1791,20 +1887,6 @@ static void Sh_GenShadowFace(dlight_t *l, shadowmesh_t *smesh, int face, float p
|
|||
memcpy(r_refdef.m_view, sav, sizeof(r_refdef.m_view));
|
||||
}
|
||||
|
||||
void Sh_Shutdown(void)
|
||||
{
|
||||
if (shadow_fbo_id)
|
||||
{
|
||||
qglDeleteRenderbuffersEXT(1, &shadow_fbo_id);
|
||||
shadow_fbo_id = 0;
|
||||
}
|
||||
if (crepuscular_fbo_id)
|
||||
{
|
||||
qglDeleteRenderbuffersEXT(1, &crepuscular_fbo_id);
|
||||
crepuscular_fbo_id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Sh_GenShadowMap (dlight_t *l, qbyte *lvis)
|
||||
{
|
||||
int f;
|
||||
|
@ -1995,7 +2077,7 @@ static void Sh_DrawShadowMapLight(dlight_t *l, vec3_t colour, qbyte *vvis)
|
|||
qglLoadIdentity();
|
||||
qglMatrixMode(GL_MODELVIEW);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
@ -2064,6 +2146,7 @@ static void Sh_DrawEntLighting(dlight_t *light, vec3_t colour)
|
|||
#endif
|
||||
static void Sh_DrawBrushModelShadow(dlight_t *dl, entity_t *e)
|
||||
{
|
||||
#ifdef GLQUAKE
|
||||
int v;
|
||||
float *v1, *v2;
|
||||
vec3_t v3, v4;
|
||||
|
@ -2162,6 +2245,7 @@ static void Sh_DrawBrushModelShadow(dlight_t *dl, entity_t *e)
|
|||
}
|
||||
|
||||
BE_PushOffsetShadow(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -2175,27 +2259,29 @@ static void Sh_DrawStencilLightShadows(dlight_t *dl, qbyte *lvis, qbyte *vvis, q
|
|||
struct shadowmesh_s *sm;
|
||||
entity_t *ent;
|
||||
|
||||
BE_PushOffsetShadow(false);
|
||||
#ifdef GLQUAKE
|
||||
if (qrenderer == QR_OPENGL)
|
||||
BE_PushOffsetShadow(false);
|
||||
#endif
|
||||
|
||||
sm = SHM_BuildShadowMesh(dl, lvis, vvis, false);
|
||||
if (!sm)
|
||||
Sh_DrawBrushModelShadow(dl, &r_worldentity);
|
||||
else
|
||||
{
|
||||
//qglEnable(GL_POLYGON_OFFSET_FILL);
|
||||
//qglPolygonOffset(shaderstate.curpolyoffset.factor, shaderstate.curpolyoffset.unit);
|
||||
|
||||
GL_SelectVBO(sm->vebo[0]);
|
||||
GL_SelectEBO(sm->vebo[1]);
|
||||
qglEnableClientState(GL_VERTEX_ARRAY);
|
||||
//draw cached world shadow mesh
|
||||
qglVertexPointer(3, GL_FLOAT, sizeof(vecV_t), sm->verts);
|
||||
qglDrawRangeElements(GL_TRIANGLES, 0, sm->numverts, sm->numindicies, GL_INDEX_TYPE, sm->indicies);
|
||||
RQuantAdd(RQUANT_SHADOWFACES, sm->numindicies);
|
||||
GL_SelectVBO(0);
|
||||
GL_SelectEBO(0);
|
||||
//qglEnable(GL_POLYGON_OFFSET_FILL);
|
||||
//qglPolygonOffset(shaderstate.curpolyoffset.factor, shaderstate.curpolyoffset.unit);
|
||||
switch (qrenderer)
|
||||
{
|
||||
#ifdef D3DQUAKE
|
||||
case QR_DIRECT3D:
|
||||
D3DBE_RenderShadowBuffer(sm->numverts, sm->d3d_vbuffer, sm->numindicies, sm->d3d_ibuffer);
|
||||
break;
|
||||
#endif
|
||||
#ifdef GLQUAKE
|
||||
case QR_OPENGL:
|
||||
GLBE_RenderShadowBuffer(sm->numverts, sm->vebo[0], sm->verts, sm->numindicies, sm->vebo[1], sm->indicies);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (!r_drawentities.value)
|
||||
return;
|
||||
|
@ -2246,8 +2332,6 @@ static void Sh_DrawStencilLightShadows(dlight_t *dl, qbyte *lvis, qbyte *vvis, q
|
|||
static qboolean Sh_DrawStencilLight(dlight_t *dl, vec3_t colour, qbyte *vvis)
|
||||
{
|
||||
int sref;
|
||||
int sfrontfail;
|
||||
int sbackfail;
|
||||
int leaf;
|
||||
qbyte *lvis;
|
||||
srect_t rect;
|
||||
|
@ -2301,165 +2385,217 @@ static qboolean Sh_DrawStencilLight(dlight_t *dl, vec3_t colour, qbyte *vvis)
|
|||
}
|
||||
bench.numlights++;
|
||||
|
||||
GLBE_SelectDLight(dl, colour);
|
||||
BE_SelectDLight(dl, colour);
|
||||
BE_SelectMode(BEM_STENCIL);
|
||||
|
||||
//The backend doesn't maintain scissor state.
|
||||
//The backend doesn't maintain stencil test state either - it needs to be active for more than just stencils, or disabled. its awkward.
|
||||
Sh_Scissor(rect);
|
||||
qglEnable(GL_SCISSOR_TEST);
|
||||
qglEnable(GL_STENCIL_TEST);
|
||||
|
||||
//FIXME: is it practical to test to see if scissors allow not clearing the stencil buffer?
|
||||
|
||||
/*we don't need all that much stencil buffer depth, and if we don't get enough or have dodgy volumes, wrap if we can*/
|
||||
#ifdef I_LIVE_IN_A_FREE_COUNTRY
|
||||
sref = 0;
|
||||
sbackfail = GL_INCR;
|
||||
sfrontfail = GL_DECR;
|
||||
if (gl_config.ext_stencil_wrap)
|
||||
{ //minimise damage...
|
||||
sbackfail = GL_INCR_WRAP_EXT;
|
||||
sdecrw = GL_DECR_WRAP_EXT;
|
||||
}
|
||||
#else
|
||||
sref = (1<<gl_stencilbits)-1; /*this is halved for two-sided stencil support, just in case there's no wrap support*/
|
||||
sbackfail = GL_DECR;
|
||||
sfrontfail = GL_INCR;
|
||||
if (gl_config.ext_stencil_wrap)
|
||||
{ //minimise damage...
|
||||
sbackfail = GL_DECR_WRAP_EXT;
|
||||
sfrontfail = GL_INCR_WRAP_EXT;
|
||||
}
|
||||
#endif
|
||||
//our stencil writes.
|
||||
if (gl_config.arb_depth_clamp)
|
||||
qglEnable(GL_DEPTH_CLAMP_ARB);
|
||||
|
||||
#if 0 //def _DEBUG
|
||||
// if (r_shadows.value == 666) //testing (visible shadow volumes)
|
||||
switch(qrenderer)
|
||||
{
|
||||
checkglerror();
|
||||
qglColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
qglColor3f(dl->color[0], dl->color[1], dl->color[2]);
|
||||
qglDisable(GL_STENCIL_TEST);
|
||||
qglEnable(GL_POLYGON_OFFSET_FILL);
|
||||
qglPolygonOffset(-1, -1);
|
||||
// qglPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
Sh_DrawStencilLightShadows(dl, lvis, vvis, false);
|
||||
qglDisable(GL_POLYGON_OFFSET_FILL);
|
||||
checkglerror();
|
||||
qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
}
|
||||
#endif
|
||||
#ifdef GLQUAKE
|
||||
case QR_OPENGL:
|
||||
{
|
||||
int sfrontfail;
|
||||
int sbackfail;
|
||||
qglEnable(GL_SCISSOR_TEST);
|
||||
qglEnable(GL_STENCIL_TEST);
|
||||
|
||||
if (qglStencilOpSeparateATI)
|
||||
{
|
||||
//FIXME: is it practical to test to see if scissors allow not clearing the stencil buffer?
|
||||
|
||||
/*we don't need all that much stencil buffer depth, and if we don't get enough or have dodgy volumes, wrap if we can*/
|
||||
#ifdef I_LIVE_IN_A_FREE_COUNTRY
|
||||
sref = 0;
|
||||
sbackfail = GL_INCR;
|
||||
sfrontfail = GL_DECR;
|
||||
if (gl_config.ext_stencil_wrap)
|
||||
{ //minimise damage...
|
||||
sbackfail = GL_INCR_WRAP_EXT;
|
||||
sdecrw = GL_DECR_WRAP_EXT;
|
||||
}
|
||||
#else
|
||||
sref = (1<<gl_stencilbits)-1; /*this is halved for two-sided stencil support, just in case there's no wrap support*/
|
||||
sbackfail = GL_DECR;
|
||||
sfrontfail = GL_INCR;
|
||||
if (gl_config.ext_stencil_wrap)
|
||||
{ //minimise damage...
|
||||
sbackfail = GL_DECR_WRAP_EXT;
|
||||
sfrontfail = GL_INCR_WRAP_EXT;
|
||||
}
|
||||
#endif
|
||||
//our stencil writes.
|
||||
if (gl_config.arb_depth_clamp)
|
||||
qglEnable(GL_DEPTH_CLAMP_ARB);
|
||||
|
||||
#if 0 //def _DEBUG
|
||||
// if (r_shadows.value == 666) //testing (visible shadow volumes)
|
||||
{
|
||||
checkglerror();
|
||||
qglColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
qglColor3f(dl->color[0], dl->color[1], dl->color[2]);
|
||||
qglDisable(GL_STENCIL_TEST);
|
||||
qglEnable(GL_POLYGON_OFFSET_FILL);
|
||||
qglPolygonOffset(-1, -1);
|
||||
// qglPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
Sh_DrawStencilLightShadows(dl, lvis, vvis, false);
|
||||
qglDisable(GL_POLYGON_OFFSET_FILL);
|
||||
checkglerror();
|
||||
qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (qglStencilOpSeparateATI)
|
||||
{
|
||||
sref/=2;
|
||||
qglClearStencil(sref);
|
||||
qglClear(GL_STENCIL_BUFFER_BIT);
|
||||
GL_CullFace(0);
|
||||
|
||||
qglStencilFunc(GL_ALWAYS, 0, ~0);
|
||||
|
||||
qglStencilOpSeparateATI(GL_BACK, GL_KEEP, sbackfail, GL_KEEP);
|
||||
qglStencilOpSeparateATI(GL_FRONT, GL_KEEP, sfrontfail, GL_KEEP);
|
||||
|
||||
Sh_DrawStencilLightShadows(dl, lvis, vvis, false);
|
||||
qglStencilOpSeparateATI(GL_FRONT_AND_BACK, GL_KEEP, GL_KEEP, GL_KEEP);
|
||||
|
||||
GL_CullFace(SHADER_CULL_FRONT);
|
||||
|
||||
qglStencilFunc(GL_EQUAL, sref, ~0);
|
||||
}
|
||||
else if (qglActiveStencilFaceEXT)
|
||||
{
|
||||
sref/=2;
|
||||
/*personally I prefer the ATI way (nvidia method)*/
|
||||
qglClearStencil(sref);
|
||||
qglClear(GL_STENCIL_BUFFER_BIT);
|
||||
GL_CullFace(0);
|
||||
|
||||
qglEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);
|
||||
|
||||
qglActiveStencilFaceEXT(GL_BACK);
|
||||
qglStencilOp(GL_KEEP, sbackfail, GL_KEEP);
|
||||
qglStencilFunc(GL_ALWAYS, 0, ~0 );
|
||||
|
||||
qglActiveStencilFaceEXT(GL_FRONT);
|
||||
qglStencilOp(GL_KEEP, sfrontfail, GL_KEEP);
|
||||
qglStencilFunc(GL_ALWAYS, 0, ~0 );
|
||||
|
||||
Sh_DrawStencilLightShadows(dl, lvis, vvis, false);
|
||||
|
||||
qglActiveStencilFaceEXT(GL_BACK);
|
||||
qglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||
qglStencilFunc(GL_ALWAYS, 0, ~0 );
|
||||
|
||||
qglActiveStencilFaceEXT(GL_FRONT);
|
||||
qglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||
qglStencilFunc(GL_EQUAL, sref, ~0 );
|
||||
|
||||
qglDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
|
||||
}
|
||||
else //your graphics card sucks and lacks efficient stencil shadow techniques.
|
||||
{ //centered around 0. Will only be increased then decreased less.
|
||||
qglClearStencil(sref);
|
||||
qglClear(GL_STENCIL_BUFFER_BIT);
|
||||
|
||||
qglStencilFunc(GL_ALWAYS, 0, ~0);
|
||||
|
||||
GL_CullFace(SHADER_CULL_BACK);
|
||||
qglStencilOp(GL_KEEP, sbackfail, GL_KEEP);
|
||||
Sh_DrawStencilLightShadows(dl, lvis, vvis, false);
|
||||
|
||||
GL_CullFace(SHADER_CULL_FRONT);
|
||||
qglStencilOp(GL_KEEP, sfrontfail, GL_KEEP);
|
||||
Sh_DrawStencilLightShadows(dl, lvis, vvis, true);
|
||||
|
||||
qglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||
qglStencilFunc(GL_EQUAL, sref, ~0);
|
||||
}
|
||||
if (gl_config.arb_depth_clamp)
|
||||
qglDisable(GL_DEPTH_CLAMP_ARB);
|
||||
//end stencil writing.
|
||||
|
||||
/*stencil writing probably changed the vertex pointer, and our backend caches it*/
|
||||
PPL_RevertToKnownState();
|
||||
|
||||
#if 0 //draw the stencil stuff to the red channel
|
||||
qglMatrixMode(GL_PROJECTION);
|
||||
qglPushMatrix();
|
||||
qglMatrixMode(GL_MODELVIEW);
|
||||
qglPushMatrix();
|
||||
GL_Set2D();
|
||||
|
||||
{
|
||||
qglColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_FALSE);
|
||||
qglStencilFunc(GL_GREATER, sref, ~0);
|
||||
R2D_ConsoleBackground(vid.height);
|
||||
|
||||
qglColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||
qglStencilFunc(GL_LESS, sref, ~0);
|
||||
R2D_ConsoleBackground(vid.height);
|
||||
|
||||
qglColorMask(GL_FALSE, GL_FALSE, GL_TRUE, GL_FALSE);
|
||||
qglStencilFunc(GL_EQUAL, sref, ~0);
|
||||
R2D_ConsoleBackground(vid.height);
|
||||
}
|
||||
|
||||
qglMatrixMode(GL_PROJECTION);
|
||||
qglPopMatrix();
|
||||
qglMatrixMode(GL_MODELVIEW);
|
||||
qglPopMatrix();
|
||||
#endif
|
||||
|
||||
|
||||
BE_SelectMode(BEM_LIGHT);
|
||||
Sh_DrawEntLighting(dl, colour);
|
||||
qglDisable(GL_STENCIL_TEST);
|
||||
qglStencilFunc( GL_ALWAYS, 0, ~0 );
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef D3DQUAKE
|
||||
case QR_DIRECT3D:
|
||||
sref = (1<<8)-1;
|
||||
sref/=2;
|
||||
qglClearStencil(sref);
|
||||
qglClear(GL_STENCIL_BUFFER_BIT);
|
||||
GL_CullFace(0);
|
||||
|
||||
qglStencilFunc(GL_ALWAYS, 0, ~0);
|
||||
/*clear the stencil buffer*/
|
||||
IDirect3DDevice9_Clear(pD3DDev9, 0, NULL, D3DCLEAR_STENCIL, D3DCOLOR_XRGB(0, 0, 0), 1.0f, sref);
|
||||
|
||||
qglStencilOpSeparateATI(GL_BACK, GL_KEEP, sbackfail, GL_KEEP);
|
||||
qglStencilOpSeparateATI(GL_FRONT, GL_KEEP, sfrontfail, GL_KEEP);
|
||||
|
||||
Sh_DrawStencilLightShadows(dl, lvis, vvis, false);
|
||||
qglStencilOpSeparateATI(GL_FRONT_AND_BACK, GL_KEEP, GL_KEEP, GL_KEEP);
|
||||
|
||||
GL_CullFace(SHADER_CULL_FRONT);
|
||||
|
||||
qglStencilFunc(GL_EQUAL, sref, ~0);
|
||||
}
|
||||
else if (qglActiveStencilFaceEXT)
|
||||
{
|
||||
sref/=2;
|
||||
/*personally I prefer the ATI way (nvidia method)*/
|
||||
qglClearStencil(sref);
|
||||
qglClear(GL_STENCIL_BUFFER_BIT);
|
||||
GL_CullFace(0);
|
||||
|
||||
qglEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);
|
||||
|
||||
qglActiveStencilFaceEXT(GL_BACK);
|
||||
qglStencilOp(GL_KEEP, sbackfail, GL_KEEP);
|
||||
qglStencilFunc(GL_ALWAYS, 0, ~0 );
|
||||
|
||||
qglActiveStencilFaceEXT(GL_FRONT);
|
||||
qglStencilOp(GL_KEEP, sfrontfail, GL_KEEP);
|
||||
qglStencilFunc(GL_ALWAYS, 0, ~0 );
|
||||
/*set up 2-sided stenciling*/
|
||||
D3DBE_Cull(0);
|
||||
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_STENCILENABLE, true);
|
||||
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
|
||||
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_TWOSIDEDSTENCILMODE, true);
|
||||
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
|
||||
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
|
||||
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
|
||||
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
|
||||
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_KEEP);
|
||||
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_INCR);
|
||||
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_KEEP);
|
||||
|
||||
/*draw the shadows*/
|
||||
Sh_DrawStencilLightShadows(dl, lvis, vvis, false);
|
||||
|
||||
qglActiveStencilFaceEXT(GL_BACK);
|
||||
qglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||
qglStencilFunc(GL_ALWAYS, 0, ~0 );
|
||||
//disable stencil writing, switch culling back to normal
|
||||
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
|
||||
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_TWOSIDEDSTENCILMODE, false);
|
||||
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_CULLMODE, D3DCULL_CW);
|
||||
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
|
||||
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_STENCILREF, sref);
|
||||
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_STENCILMASK, ~0);
|
||||
|
||||
qglActiveStencilFaceEXT(GL_FRONT);
|
||||
qglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||
qglStencilFunc(GL_EQUAL, sref, ~0 );
|
||||
/*draw the light*/
|
||||
BE_SelectMode(BEM_LIGHT);
|
||||
Sh_DrawEntLighting(dl, colour);
|
||||
|
||||
qglDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
|
||||
|
||||
GL_CullFace(SHADER_CULL_FRONT);
|
||||
}
|
||||
else //your graphics card sucks and lacks efficient stencil shadow techniques.
|
||||
{ //centered around 0. Will only be increased then decreased less.
|
||||
qglClearStencil(sref);
|
||||
qglClear(GL_STENCIL_BUFFER_BIT);
|
||||
|
||||
qglStencilFunc(GL_ALWAYS, 0, ~0);
|
||||
|
||||
GL_CullFace(SHADER_CULL_BACK);
|
||||
qglStencilOp(GL_KEEP, sbackfail, GL_KEEP);
|
||||
Sh_DrawStencilLightShadows(dl, lvis, vvis, false);
|
||||
|
||||
GL_CullFace(SHADER_CULL_FRONT);
|
||||
qglStencilOp(GL_KEEP, sfrontfail, GL_KEEP);
|
||||
Sh_DrawStencilLightShadows(dl, lvis, vvis, true);
|
||||
|
||||
qglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||
qglStencilFunc(GL_EQUAL, sref, ~0);
|
||||
}
|
||||
if (gl_config.arb_depth_clamp)
|
||||
qglDisable(GL_DEPTH_CLAMP_ARB);
|
||||
//end stencil writing.
|
||||
|
||||
#if 0 //draw the stencil stuff to the red channel
|
||||
qglMatrixMode(GL_PROJECTION);
|
||||
qglPushMatrix();
|
||||
qglMatrixMode(GL_MODELVIEW);
|
||||
qglPushMatrix();
|
||||
GL_Set2D();
|
||||
|
||||
{
|
||||
qglColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_FALSE);
|
||||
qglStencilFunc(GL_GREATER, sref, ~0);
|
||||
R2D_ConsoleBackground(vid.height);
|
||||
|
||||
qglColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||
qglStencilFunc(GL_LESS, sref, ~0);
|
||||
R2D_ConsoleBackground(vid.height);
|
||||
|
||||
qglColorMask(GL_FALSE, GL_FALSE, GL_TRUE, GL_FALSE);
|
||||
qglStencilFunc(GL_EQUAL, sref, ~0);
|
||||
R2D_ConsoleBackground(vid.height);
|
||||
}
|
||||
|
||||
qglMatrixMode(GL_PROJECTION);
|
||||
qglPopMatrix();
|
||||
qglMatrixMode(GL_MODELVIEW);
|
||||
qglPopMatrix();
|
||||
/*okay, no more stencil stuff*/
|
||||
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_STENCILENABLE, false);
|
||||
break;
|
||||
#endif
|
||||
|
||||
PPL_RevertToKnownState();
|
||||
|
||||
BE_SelectMode(BEM_LIGHT);
|
||||
Sh_DrawEntLighting(dl, colour);
|
||||
|
||||
qglDisable(GL_STENCIL_TEST);
|
||||
qglStencilFunc( GL_ALWAYS, 0, ~0 );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -2517,13 +2653,22 @@ static void Sh_DrawShadowlessLight(dlight_t *dl, vec3_t colour, qbyte *vvis)
|
|||
bench.numscissorculled++;
|
||||
return; //was culled.
|
||||
}
|
||||
qglDisable(GL_SCISSOR_TEST);
|
||||
if (qglDepthBoundsEXT)
|
||||
qglDisable(GL_DEPTH_BOUNDS_TEST_EXT);
|
||||
|
||||
switch(qrenderer)
|
||||
{
|
||||
#ifdef GLQUAKE
|
||||
case QR_OPENGL:
|
||||
//so state doesn't linger
|
||||
qglDisable(GL_SCISSOR_TEST);
|
||||
if (qglDepthBoundsEXT)
|
||||
qglDisable(GL_DEPTH_BOUNDS_TEST_EXT);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
bench.numlights++;
|
||||
|
||||
GLBE_SelectDLight(dl, colour);
|
||||
BE_SelectDLight(dl, colour);
|
||||
BE_SelectMode(BEM_LIGHT);
|
||||
Sh_DrawEntLighting(dl, colour);
|
||||
}
|
||||
|
@ -2531,6 +2676,7 @@ static void Sh_DrawShadowlessLight(dlight_t *dl, vec3_t colour, qbyte *vvis)
|
|||
void GLBE_SubmitMeshes (qboolean drawworld, batch_t **blist, int start, int stop);
|
||||
void Sh_DrawCrepuscularLight(dlight_t *dl, float *colours, batch_t **batches)
|
||||
{
|
||||
#ifdef GLQUAKE
|
||||
static mesh_t mesh;
|
||||
static vecV_t xyz[4] =
|
||||
{
|
||||
|
@ -2551,12 +2697,15 @@ void Sh_DrawCrepuscularLight(dlight_t *dl, float *colours, batch_t **batches)
|
|||
0,1,2,
|
||||
0,2,3
|
||||
};
|
||||
if (qrenderer != QR_OPENGL)
|
||||
return;
|
||||
|
||||
mesh.numindexes = 6;
|
||||
mesh.numvertexes = 4;
|
||||
mesh.xyz_array = xyz;
|
||||
mesh.st_array = tc;
|
||||
mesh.indexes = idx;
|
||||
#if 1
|
||||
|
||||
/*
|
||||
a crepuscular light (seriously, that's the correct spelling) is one that gives 'god rays', rather than regular light.
|
||||
our implementation doesn't cast shadows. this allows it to actually be outside the map, and to shine through cloud layers in the sky.
|
||||
|
@ -2666,20 +2815,38 @@ void Sh_DrawLights(qbyte *vis, batch_t **mbatches)
|
|||
return;
|
||||
}
|
||||
|
||||
/*no stencil?*/
|
||||
if (gl_config.nofixedfunc)
|
||||
switch(qrenderer)
|
||||
{
|
||||
Con_Printf("FTE does not support stencil shadows without a fixed-function pipeline\n");
|
||||
r_shadow_realtime_world.ival = 0;
|
||||
r_shadow_realtime_dlight.ival = 0;
|
||||
return;
|
||||
}
|
||||
#ifdef GLQUAKE
|
||||
case QR_OPENGL:
|
||||
/*no stencil?*/
|
||||
if (gl_config.nofixedfunc)
|
||||
{
|
||||
Con_Printf("FTE does not support stencil shadows without a fixed-function pipeline\n");
|
||||
r_shadow_realtime_world.ival = 0;
|
||||
r_shadow_realtime_dlight.ival = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!gl_config.arb_shader_objects)
|
||||
{
|
||||
Con_Printf("Missing GL extensions: switching off realtime lighting.\n");
|
||||
r_shadow_realtime_world.ival = 0;
|
||||
r_shadow_realtime_dlight.ival = 0;
|
||||
if (!gl_config.arb_shader_objects)
|
||||
{
|
||||
Con_Printf("Missing GL extensions: switching off realtime lighting.\n");
|
||||
r_shadow_realtime_world.ival = 0;
|
||||
r_shadow_realtime_dlight.ival = 0;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef D3DQUAKE
|
||||
case QR_DIRECT3D:
|
||||
#ifdef GLQUAKE
|
||||
//the code still has a lot of ifdefs, so will crash if you try it in a merged build.
|
||||
//its not really usable in d3d-only builds either, so no great loss.
|
||||
return;
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2723,7 +2890,9 @@ void Sh_DrawLights(qbyte *vis, batch_t **mbatches)
|
|||
}
|
||||
else if (dl->flags & LFLAG_SHADOWMAP)
|
||||
{
|
||||
#ifdef GLQUAKE
|
||||
Sh_DrawShadowMapLight(dl, colour, vis);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2731,9 +2900,17 @@ void Sh_DrawLights(qbyte *vis, batch_t **mbatches)
|
|||
}
|
||||
}
|
||||
|
||||
qglDisable(GL_SCISSOR_TEST);
|
||||
if (qglDepthBoundsEXT)
|
||||
qglDisable(GL_DEPTH_BOUNDS_TEST_EXT);
|
||||
switch(qrenderer)
|
||||
{
|
||||
#ifdef GLQUAKE
|
||||
case QR_OPENGL:
|
||||
qglDisable(GL_SCISSOR_TEST);
|
||||
if (qglDepthBoundsEXT)
|
||||
qglDisable(GL_DEPTH_BOUNDS_TEST_EXT);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
BE_SelectMode(BEM_STANDARD);
|
||||
|
||||
// if (developer.value)
|
||||
|
|
|
@ -196,44 +196,63 @@ BINDTEXFUNCPTR bindTexFunc;
|
|||
#define DEBUG
|
||||
#endif
|
||||
#if defined(DEBUG)
|
||||
typedef void (APIENTRY *GLDEBUGPROCAMD)(GLuint id,
|
||||
GLenum category,
|
||||
typedef void (APIENTRY *GLDEBUGPROCARB)(GLenum source,
|
||||
GLenum type,
|
||||
GLuint id,
|
||||
GLenum severity,
|
||||
GLsizei lengt,
|
||||
GLsizei length,
|
||||
const GLchar* message,
|
||||
GLvoid* userParam);
|
||||
void (APIENTRY *qglDebugMessageEnableAMD)(GLenum category,
|
||||
GLenum severity,
|
||||
void (APIENTRY *qglDebugMessageControlARB)(enum source,
|
||||
enum type,
|
||||
enum severity,
|
||||
GLsizei count,
|
||||
const GLuint* ids,
|
||||
GLboolean enabled);
|
||||
void (APIENTRY *qglDebugMessageInsertAMD)(enum category,
|
||||
enum severity,
|
||||
void (APIENTRY *qglDebugMessageInsertARB)(enum source,
|
||||
enum type,
|
||||
GLuint id,
|
||||
enum severity,
|
||||
GLsizei length,
|
||||
const char* buf);
|
||||
void (APIENTRY *qglDebugMessageCallbackAMD)(GLDEBUGPROCAMD callback,
|
||||
void (APIENTRY *qglDebugMessageCallbackARB)(GLDEBUGPROCARB callback,
|
||||
void* userParam);
|
||||
GLuint (APIENTRY *qglGetDebugMessageLogAMD)(GLuint count,
|
||||
GLuint (APIENTRY *qglGetDebugMessageLogARB)(GLuint count,
|
||||
GLsizei bufsize,
|
||||
GLenum* categories,
|
||||
GLuint* severities,
|
||||
GLenum* sources,
|
||||
GLenum* types,
|
||||
GLuint* ids,
|
||||
GLsizei* lengths,
|
||||
char* message);
|
||||
GLuint* severities,
|
||||
GLsizei* lengths,
|
||||
char* messageLog);
|
||||
|
||||
#define GL_DEBUG_CATEGORY_API_ERROR_AMD 0x9149
|
||||
#define GL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD 0x914A
|
||||
#define GL_DEBUG_CATEGORY_DEPRECATION_AMD 0x914B
|
||||
#define GL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR_AMD 0x914C
|
||||
#define GL_DEBUG_CATEGORY_PERFORMANCE_AMD 0x914D
|
||||
#define GL_DEBUG_CATEGORY_SHADER_COMPILER_AMD 0x914E
|
||||
#define GL_DEBUG_CATEGORY_APPLICATION_AMD 0x914F
|
||||
#define GL_DEBUG_CATEGORY_OTHER_AMD 0x9150
|
||||
#define GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB 0x8242
|
||||
#define GL_MAX_DEBUG_MESSAGE_LENGTH_ARB 0x9143
|
||||
#define GL_MAX_DEBUG_LOGGED_MESSAGES_ARB 0x9144
|
||||
#define GL_DEBUG_LOGGED_MESSAGES_ARB 0x9145
|
||||
#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB 0x8243
|
||||
#define GL_DEBUG_CALLBACK_FUNCTION_ARB 0x8244
|
||||
#define GL_DEBUG_CALLBACK_USER_PARAM_ARB 0x8245
|
||||
#define GL_DEBUG_SOURCE_API_ARB 0x8246
|
||||
#define GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB 0x8247
|
||||
#define GL_DEBUG_SOURCE_SHADER_COMPILER_ARB 0x8248
|
||||
#define GL_DEBUG_SOURCE_THIRD_PARTY_ARB 0x8249
|
||||
#define GL_DEBUG_SOURCE_APPLICATION_ARB 0x824A
|
||||
#define GL_DEBUG_SOURCE_OTHER_ARB 0x824B
|
||||
#define GL_DEBUG_TYPE_ERROR_ARB 0x824C
|
||||
#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB 0x824D
|
||||
#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB 0x824E
|
||||
#define GL_DEBUG_TYPE_PORTABILITY_ARB 0x824F
|
||||
#define GL_DEBUG_TYPE_PERFORMANCE_ARB 0x8250
|
||||
#define GL_DEBUG_TYPE_OTHER_ARB 0x8251
|
||||
#define GL_DEBUG_SEVERITY_HIGH_ARB 0x9146
|
||||
#define GL_DEBUG_SEVERITY_MEDIUM_ARB 0x9147
|
||||
#define GL_DEBUG_SEVERITY_LOW_ARB 0x9148
|
||||
|
||||
|
||||
void (APIENTRY myGLDEBUGPROCAMD)(GLuint id,
|
||||
GLenum category,
|
||||
void (APIENTRY myGLDEBUGPROCAMD)(GLenum source,
|
||||
GLenum type,
|
||||
GLuint id,
|
||||
GLenum severity,
|
||||
GLsizei length,
|
||||
const GLchar* message,
|
||||
|
@ -242,32 +261,26 @@ void (APIENTRY myGLDEBUGPROCAMD)(GLuint id,
|
|||
#ifndef _WIN32
|
||||
#define OutputDebugString(s) puts(s)
|
||||
#endif
|
||||
switch(category)
|
||||
switch(type)
|
||||
{
|
||||
case GL_DEBUG_CATEGORY_API_ERROR_AMD:
|
||||
OutputDebugString("glerr: ");
|
||||
case GL_DEBUG_TYPE_ERROR_ARB:
|
||||
OutputDebugString("Error: ");
|
||||
break;
|
||||
case GL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD:
|
||||
OutputDebugString("glwsys: ");
|
||||
case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB:
|
||||
OutputDebugString("Depricated: ");
|
||||
break;
|
||||
case GL_DEBUG_CATEGORY_DEPRECATION_AMD:
|
||||
OutputDebugString("gldepr: ");
|
||||
case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB:
|
||||
OutputDebugString("Undefined: ");
|
||||
break;
|
||||
case GL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR_AMD:
|
||||
OutputDebugString("glundef: ");
|
||||
case GL_DEBUG_TYPE_PORTABILITY_ARB:
|
||||
OutputDebugString("Portability: ");
|
||||
break;
|
||||
case GL_DEBUG_CATEGORY_PERFORMANCE_AMD:
|
||||
OutputDebugString("glperf: ");
|
||||
break;
|
||||
case GL_DEBUG_CATEGORY_SHADER_COMPILER_AMD:
|
||||
OutputDebugString("glshad: ");
|
||||
break;
|
||||
case GL_DEBUG_CATEGORY_APPLICATION_AMD:
|
||||
OutputDebugString("glappm: ");
|
||||
case GL_DEBUG_TYPE_PERFORMANCE_ARB:
|
||||
OutputDebugString("Performance: ");
|
||||
break;
|
||||
default:
|
||||
case GL_DEBUG_CATEGORY_OTHER_AMD:
|
||||
OutputDebugString("glothr: ");
|
||||
case GL_DEBUG_TYPE_OTHER_ARB:
|
||||
OutputDebugString("Other: ");
|
||||
break;
|
||||
}
|
||||
OutputDebugString(message);
|
||||
|
@ -660,19 +673,19 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name), float ver)
|
|||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
if (GL_CheckExtension("GL_AMD_debug_output"))
|
||||
if (GL_CheckExtension("GL_ARB_debug_output"))
|
||||
{
|
||||
qglDebugMessageEnableAMD = (void *)getglext("glDebugMessageEnableAMD");
|
||||
qglDebugMessageInsertAMD = (void *)getglext("glDebugMessageInsertAMD");
|
||||
qglDebugMessageCallbackAMD = (void *)getglext("glDebugMessageCallbackAMD");
|
||||
qglGetDebugMessageLogAMD = (void *)getglext("glGetDebugMessageLogAMD");
|
||||
qglDebugMessageControlARB = (void *)getglext("glDebugMessageControlARB");
|
||||
qglDebugMessageInsertARB = (void *)getglext("glDebugMessageInsertARB");
|
||||
qglDebugMessageCallbackARB = (void *)getglext("glDebugMessageCallbackARB");
|
||||
qglGetDebugMessageLogARB = (void *)getglext("glGetDebugMessageLogARB");
|
||||
}
|
||||
else
|
||||
{
|
||||
qglDebugMessageEnableAMD = NULL;
|
||||
qglDebugMessageInsertAMD = NULL;
|
||||
qglDebugMessageCallbackAMD = NULL;
|
||||
qglGetDebugMessageLogAMD = NULL;
|
||||
qglDebugMessageControlARB = NULL;
|
||||
qglDebugMessageInsertARB = NULL;
|
||||
qglDebugMessageCallbackARB = NULL;
|
||||
qglGetDebugMessageLogARB = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -1334,10 +1347,10 @@ void GL_Init(void *(*getglfunction) (char *name))
|
|||
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
|
||||
#ifdef DEBUG
|
||||
if (qglDebugMessageEnableAMD)
|
||||
qglDebugMessageEnableAMD(0, 0, 0, NULL, true);
|
||||
if (qglDebugMessageCallbackAMD)
|
||||
qglDebugMessageCallbackAMD(myGLDEBUGPROCAMD, NULL);
|
||||
if (qglDebugMessageControlARB)
|
||||
qglDebugMessageControlARB(0, 0, 0, 0, NULL, true);
|
||||
if (qglDebugMessageCallbackARB)
|
||||
qglDebugMessageCallbackARB(myGLDEBUGPROCAMD, NULL);
|
||||
qglGetError(); /*suck up the invalid operation error for non-debug contexts*/
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -173,7 +173,6 @@ typedef struct {
|
|||
qboolean ext_stencil_wrap;
|
||||
qboolean arb_depth_clamp;
|
||||
int ext_texture_filter_anisotropic;
|
||||
int maxtmus; //max texture units
|
||||
} gl_config_t;
|
||||
|
||||
extern gl_config_t gl_config;
|
||||
|
@ -350,9 +349,9 @@ void GL_SetupSceneProcessingTextures (void);
|
|||
//
|
||||
// gl_alias.c
|
||||
//
|
||||
#ifdef GLQUAKE
|
||||
void R_DrawGAliasShadowVolume(entity_t *e, vec3_t lightpos, float radius);
|
||||
|
||||
#ifdef GLQUAKE
|
||||
//misc model formats
|
||||
void R_DrawHLModel(entity_t *curent);
|
||||
|
||||
|
@ -371,6 +370,10 @@ void GLR_MarkQ2Lights (dlight_t *light, int bit, mnode_t *node);
|
|||
int GLR_LightPoint (vec3_t p);
|
||||
#endif
|
||||
void GLQ3_LightGrid(model_t *mod, vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir);
|
||||
void R_ReloadRTLights_f(void);
|
||||
void R_LoadRTLights(void);
|
||||
void R_ImportRTLights(char *entlump);
|
||||
void R_SaveRTLights_f(void);
|
||||
|
||||
//
|
||||
// gl_heightmap.c
|
||||
|
|
|
@ -702,5 +702,10 @@ typedef void (APIENTRY * PFNGLUNLOCKARRAYSEXTPROC) (void);
|
|||
#define GL_DEPTH_CLAMP_ARB 0x864F
|
||||
#endif
|
||||
|
||||
#ifndef GL_TEXTURE_BASE_LEVEL //GL_SGIS_texture_lod (core gl 1.2)
|
||||
#define GL_TEXTURE_BASE_LEVEL 0x813c
|
||||
#define GL_TEXTURE_MAX_LEVEL 0x813d
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue