d3d renderer works a little better in q3.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3639 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2010-11-10 03:32:47 +00:00
parent 899d4d3334
commit f575777728
23 changed files with 864 additions and 314 deletions

View file

@ -1650,8 +1650,6 @@ void CL_ParseDownload (void)
} }
CL_DownloadFailed(cls.downloadremotename); CL_DownloadFailed(cls.downloadremotename);
CL_RequestNextDownload ();
return; return;
} }

View file

@ -489,7 +489,6 @@ cinematics_t *CIN_PlayCinematic (char *arg)
} }
else else
{ {
cin->cinematictime = 0; // done
Con_Printf(CON_WARNING "Cinematic %s not found.\n", name); Con_Printf(CON_WARNING "Cinematic %s not found.\n", name);
} }
return cin; return cin;

View file

@ -1064,7 +1064,7 @@ qboolean Media_Roq_DecodeFrame (cin_t *cin, qboolean nosound)
{ {
float curtime = Sys_DoubleTime(); float curtime = Sys_DoubleTime();
if ((int)(cin->filmlasttime*30) == (int)((float)realtime*30)) if ((int)(cin->filmlasttime*30) == (int)((float)realtime*30) && cin->outtype != TF_INVALID)
{ {
cin->outunchanged = !!cin->outtype; cin->outunchanged = !!cin->outtype;
return true; return true;

View file

@ -82,7 +82,6 @@ extern void (*R_NewMap) (void);
extern void (*R_PreNewMap) (void); extern void (*R_PreNewMap) (void);
extern int (*R_LightPoint) (vec3_t point); extern int (*R_LightPoint) (vec3_t point);
extern void (*R_PushDlights) (void);
extern void (*R_AddStain) (vec3_t org, float red, float green, float blue, float radius); extern void (*R_AddStain) (vec3_t org, float red, float green, float blue, float radius);
extern void (*R_LessenStains) (void); extern void (*R_LessenStains) (void);
@ -200,7 +199,6 @@ typedef struct rendererinfo_s {
void (*R_PreNewMap) (void); void (*R_PreNewMap) (void);
int (*R_LightPoint) (vec3_t point); int (*R_LightPoint) (vec3_t point);
void (*R_PushDlights) (void);
void (*R_AddStain) (vec3_t org, float red, float green, float blue, float radius); void (*R_AddStain) (vec3_t org, float red, float green, float blue, float radius);
void (*R_LessenStains) (void); void (*R_LessenStains) (void);

View file

@ -1952,7 +1952,7 @@ void Surf_GenBrushBatches(batch_t **batches, entity_t *ent)
currententity = ent; currententity = ent;
currentmodel = ent->model; currentmodel = ent->model;
if (model->nummodelsurfaces != 0 && r_dynamic.value) if (model->nummodelsurfaces != 0 && r_dynamic.ival)
{ {
for (k=rtlights_first; k<RTL_FIRST; k++) for (k=rtlights_first; k<RTL_FIRST; k++)
{ {
@ -2056,6 +2056,13 @@ void Surf_DrawWorld (void)
qbyte *vis; qbyte *vis;
RSpeedLocals(); RSpeedLocals();
if (r_refdef.flags & Q2RDF_NOWORLDMODEL || !cl.worldmodel)
{
r_refdef.flags |= Q2RDF_NOWORLDMODEL;
BE_DrawWorld(NULL);
return;
}
Surf_SetupFrame(); Surf_SetupFrame();
currentmodel = cl.worldmodel; currentmodel = cl.worldmodel;

View file

@ -346,6 +346,7 @@ double Media_TweekCaptureFrameTime(double time);
void MYgluPerspective(double fovx, double fovy, double zNear, double zFar); void MYgluPerspective(double fovx, double fovy, double zNear, double zFar);
void R_PushDlights (void);
qbyte *R_MarkLeaves_Q1 (void); qbyte *R_MarkLeaves_Q1 (void);
qbyte *R_CalcVis_Q1 (void); qbyte *R_CalcVis_Q1 (void);
qbyte *R_MarkLeaves_Q2 (void); qbyte *R_MarkLeaves_Q2 (void);

View file

@ -86,8 +86,8 @@ cvar_t r_fastsky = CVARF ("r_fastsky", "0",
CVAR_SHADERSYSTEM); CVAR_SHADERSYSTEM);
cvar_t r_fastskycolour = CVARF ("r_fastskycolour", "0", cvar_t r_fastskycolour = CVARF ("r_fastskycolour", "0",
CVAR_RENDERERCALLBACK|CVAR_SHADERSYSTEM); CVAR_RENDERERCALLBACK|CVAR_SHADERSYSTEM);
cvar_t r_fb_bmodels = CVARF("gl_fb_bmodels", "1", cvar_t r_fb_bmodels = CVARAF("r_fb_bmodels", "1",
CVAR_SEMICHEAT|CVAR_RENDERERLATCH); "gl_fb_bmodels", CVAR_SEMICHEAT|CVAR_RENDERERLATCH);
cvar_t r_fb_models = CVARAF ("r_fb_models", "1", cvar_t r_fb_models = CVARAF ("r_fb_models", "1",
"gl_fb_models", CVAR_SEMICHEAT|CVAR_RENDERERLATCH); "gl_fb_models", CVAR_SEMICHEAT|CVAR_RENDERERLATCH);
cvar_t r_skin_overlays = SCVARF ("r_skin_overlays", "1", cvar_t r_skin_overlays = SCVARF ("r_skin_overlays", "1",
@ -429,7 +429,6 @@ void GLRenderer_Init(void)
Cvar_Register (&gl_overbright, GRAPHICALNICETIES); Cvar_Register (&gl_overbright, GRAPHICALNICETIES);
Cvar_Register (&gl_overbright_all, GRAPHICALNICETIES); Cvar_Register (&gl_overbright_all, GRAPHICALNICETIES);
Cvar_Register (&gl_dither, GRAPHICALNICETIES); Cvar_Register (&gl_dither, GRAPHICALNICETIES);
Cvar_Register (&r_fb_bmodels, GRAPHICALNICETIES);
Cvar_Register (&gl_ati_truform, GRAPHICALNICETIES); Cvar_Register (&gl_ati_truform, GRAPHICALNICETIES);
Cvar_Register (&gl_ati_truform_type, GRAPHICALNICETIES); Cvar_Register (&gl_ati_truform_type, GRAPHICALNICETIES);
@ -608,6 +607,7 @@ void Renderer_Init(void)
Cvar_Register (&r_drawflat, GRAPHICALNICETIES); Cvar_Register (&r_drawflat, GRAPHICALNICETIES);
Cvar_Register (&r_menutint, GRAPHICALNICETIES); Cvar_Register (&r_menutint, GRAPHICALNICETIES);
Cvar_Register (&r_fb_bmodels, GRAPHICALNICETIES);
Cvar_Register (&r_fb_models, GRAPHICALNICETIES); Cvar_Register (&r_fb_models, GRAPHICALNICETIES);
Cvar_Register (&r_skin_overlays, GRAPHICALNICETIES); Cvar_Register (&r_skin_overlays, GRAPHICALNICETIES);
@ -704,7 +704,6 @@ void (*R_NewMap) (void);
void (*R_PreNewMap) (void); void (*R_PreNewMap) (void);
int (*R_LightPoint) (vec3_t point); int (*R_LightPoint) (vec3_t point);
void (*R_PushDlights) (void);
void (*R_AddStain) (vec3_t org, float red, float green, float blue, float radius); void (*R_AddStain) (vec3_t org, float red, float green, float blue, float radius);
void (*R_LessenStains) (void); void (*R_LessenStains) (void);
@ -784,7 +783,6 @@ rendererinfo_t dedicatedrendererinfo = {
NULL, //R_NewMap; NULL, //R_NewMap;
NULL, //R_PreNewMap NULL, //R_PreNewMap
NULL, //R_LightPoint; NULL, //R_LightPoint;
NULL, //R_PushDlights;
NULL, //R_AddStain; NULL, //R_AddStain;
@ -1323,7 +1321,6 @@ void R_SetRenderer(rendererinfo_t *ri)
R_NewMap = ri->R_NewMap; R_NewMap = ri->R_NewMap;
R_PreNewMap = ri->R_PreNewMap; R_PreNewMap = ri->R_PreNewMap;
R_LightPoint = ri->R_LightPoint; R_LightPoint = ri->R_LightPoint;
R_PushDlights = ri->R_PushDlights;
R_AddStain = ri->R_AddStain; R_AddStain = ri->R_AddStain;
R_LessenStains = ri->R_LessenStains; R_LessenStains = ri->R_LessenStains;

View file

@ -1774,6 +1774,14 @@ void Sbar_DrawScoreboard (void)
if (cls.protocol == CP_QUAKE2) if (cls.protocol == CP_QUAKE2)
return; return;
#ifndef CLIENTONLY
/*no scoreboard in single player (if you want bots, set deathmatch)*/
if (sv.state && cls.gamemode == GAME_COOP && sv.allocated_client_slots == 1)
{
return;
}
#endif
for (pnum = 0; pnum < cl.splitclients; pnum++) for (pnum = 0; pnum < cl.splitclients; pnum++)
{ {
if (cl.stats[pnum][STAT_HEALTH] <= 0) if (cl.stats[pnum][STAT_HEALTH] <= 0)
@ -1782,19 +1790,6 @@ void Sbar_DrawScoreboard (void)
if (deadcount == cl.splitclients && !cl.spectator) if (deadcount == cl.splitclients && !cl.spectator)
{ {
#ifndef CLIENTONLY
if (sv.state && cls.gamemode == GAME_COOP)
{
for (pnum = 0; pnum < sv.allocated_client_slots; pnum++)
{
if (svs.clients[pnum].state)
if (svs.clients[pnum].netchan.remote_address.type != NA_LOOPBACK)
break;
}
if (pnum == sv.allocated_client_slots)
return;
}
#endif
if (cl.teamplay > 0 && !sb_showscores) if (cl.teamplay > 0 && !sb_showscores)
Sbar_TeamOverlay(); Sbar_TeamOverlay();
else else
@ -1845,7 +1840,6 @@ void Sbar_Hexen2DrawInventory(int pnum)
if (sb_hexen2_item_time[pnum]+3 < realtime) if (sb_hexen2_item_time[pnum]+3 < realtime)
return; return;
#if 1
for (i = sb_hexen2_cur_item[pnum]; i < 15; i++) for (i = sb_hexen2_cur_item[pnum]; i < 15; i++)
if (sb_hexen2_cur_item[pnum] == i || cl.stats[pnum][STAT_H2_CNT_TORCH+i] > 0) if (sb_hexen2_cur_item[pnum] == i || cl.stats[pnum][STAT_H2_CNT_TORCH+i] > 0)
activeright++; activeright++;
@ -1877,23 +1871,6 @@ void Sbar_Hexen2DrawInventory(int pnum)
Sbar_Hexen2DrawItem(pnum, x, y, i); Sbar_Hexen2DrawItem(pnum, x, y, i);
x+=33; x+=33;
} }
#elif 1
for (i = 0, x=320/2-114; i < 7; i++, x+=33)
{
if ((sb_hexen2_cur_item[pnum]-3+i+30)%15 == sb_hexen2_cur_item[pnum])
Sbar_DrawPic(x+9, y-12, 11, 11, Draw_SafeCachePic("gfx/artisel.lmp"));
Sbar_Hexen2DrawItem(pnum, x, y, (sb_hexen2_cur_item[pnum]-3+i+30)%15);
}
#else
for (i = 0, x=320/2; i < 3; i++, x+=33)
{
Sbar_Hexen2DrawItem(pnum, x, y, (sb_hexen2_cur_item[pnum]+1+i)%15);
}
for (i = 0, x=320/2-33; i < 3; i++, x-=33)
{
Sbar_Hexen2DrawItem(pnum, x, y, (sb_hexen2_cur_item[pnum]-1-i+45)%15);
}
#endif
} }
void Sbar_Hexen2DrawExtra (int pnum) void Sbar_Hexen2DrawExtra (int pnum)
@ -2314,12 +2291,6 @@ void Sbar_Draw (void)
Sbar_DrawString (0, -8, va("Health: %i", cl.stats[pnum][STAT_HEALTH])); Sbar_DrawString (0, -8, va("Health: %i", cl.stats[pnum][STAT_HEALTH]));
Sbar_DrawString (0, -16, va(" Armor: %i", cl.stats[pnum][STAT_ARMOR])); Sbar_DrawString (0, -16, va(" Armor: %i", cl.stats[pnum][STAT_ARMOR]));
if (cl.stats[pnum][STAT_H2_BLUEMANA])
Sbar_DrawString (0, -24, va(" Blue: %i", cl.stats[pnum][STAT_H2_BLUEMANA]));
if (cl.stats[pnum][STAT_H2_GREENMANA])
Sbar_DrawString (0, -32, va(" Green: %i", cl.stats[pnum][STAT_H2_GREENMANA]));
continue; continue;
} }
@ -2347,7 +2318,7 @@ void Sbar_Draw (void)
} }
else else
{ {
if (sb_showscores || cl.stats[pnum][STAT_HEALTH] <= 0) if (sb_showscores || sb_showteamscores || cl.stats[pnum][STAT_HEALTH] <= 0)
Sbar_SoloScoreboard (); Sbar_SoloScoreboard ();
else if (cls.gamemode != GAME_DEATHMATCH) else if (cls.gamemode != GAME_DEATHMATCH)
Sbar_CoopScoreboard (); Sbar_CoopScoreboard ();
@ -2362,7 +2333,7 @@ void Sbar_Draw (void)
} }
} }
} }
else if (sb_showscores || (cl.stats[pnum][STAT_HEALTH] <= 0 && cl.splitclients == 1)) else if (sb_showscores || sb_showteamscores || (cl.stats[pnum][STAT_HEALTH] <= 0 && cl.splitclients == 1))
{ {
if (!pnum) if (!pnum)
{ {

View file

@ -538,7 +538,31 @@ void Skin_NextDownload (void)
if (!*sc->skin->name) if (!*sc->skin->name)
continue; continue;
CL_CheckOrEnqueDownloadFile(va("skins/%s.pcx", sc->skin->name), NULL, 0); if (cls.protocol == CP_QUAKE2)
{
int j;
char *slash;
slash = strchr(sc->skin->name, '/');
if (slash)
{
*slash = 0;
CL_CheckOrEnqueDownloadFile(va("players/%s/tris.md2", sc->skin->name), NULL, 0);
for (j = 0; j < MAX_MODELS; j++)
{
if (cl.model_name[j][0] == '#')
CL_CheckOrEnqueDownloadFile(va("players/%s/%s", sc->skin->name, cl.model_name[j]+1), NULL, 0);
}
for (j = 0; j < MAX_SOUNDS; j++)
{
if (cl.sound_name[j][0] == '*')
CL_CheckOrEnqueDownloadFile(va("players/%s/%s", sc->skin->name, cl.sound_name[j]+1), NULL, 0);
}
*slash = '/';
CL_CheckOrEnqueDownloadFile(va("players/%s.pcx", sc->skin->name), NULL, 0);
}
}
else
CL_CheckOrEnqueDownloadFile(va("skins/%s.pcx", sc->skin->name), NULL, 0);
} }
// now load them in for real // now load them in for real

View file

@ -77,11 +77,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define AVAIL_FREETYPE #define AVAIL_FREETYPE
#endif #endif
#ifdef _WIN64
#undef AVAIL_PNGLIB
#undef AVAIL_ZLIB
#endif
#define ODE_DYNAMIC #define ODE_DYNAMIC
#ifdef NO_PNG #ifdef NO_PNG

View file

@ -14,7 +14,11 @@
#endif #endif
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma comment(lib, MSVCLIBSPATH "zlib.lib") # ifdef _WIN64
# pragma comment (lib, "../libs/zlib64.lib")
# else
# pragma comment (lib, "../libs/zlib.lib")
# endif
#endif #endif
hashtable_t filesystemhash; hashtable_t filesystemhash;
@ -613,6 +617,7 @@ char *FS_GetPackHashes(char *buffer, int buffersize, qboolean referencedonly)
} }
char *FS_GetPackNames(char *buffer, int buffersize, qboolean referencedonly) char *FS_GetPackNames(char *buffer, int buffersize, qboolean referencedonly)
{ {
char temp[MAX_OSPATH];
searchpath_t *search; searchpath_t *search;
buffersize--; buffersize--;
*buffer = 0; *buffer = 0;
@ -621,7 +626,8 @@ char *FS_GetPackNames(char *buffer, int buffersize, qboolean referencedonly)
{ {
for (search = com_purepaths ; search ; search = search->nextpure) for (search = com_purepaths ; search ; search = search->nextpure)
{ {
Q_strncatz(buffer, va("%s ", search->purepath), buffersize); COM_StripExtension(search->purepath, temp, sizeof(temp));
Q_strncatz(buffer, va("%s ", temp), buffersize);
} }
return buffer; return buffer;
} }
@ -633,7 +639,8 @@ char *FS_GetPackNames(char *buffer, int buffersize, qboolean referencedonly)
search->crc_check = search->funcs->GeneratePureCRC(search->handle, 0, 0); search->crc_check = search->funcs->GeneratePureCRC(search->handle, 0, 0);
if (search->crc_check) if (search->crc_check)
{ {
Q_strncatz(buffer, va("%s ", search->purepath), buffersize); COM_StripExtension(search->purepath, temp, sizeof(temp));
Q_strncatz(buffer, va("%s ", temp), buffersize);
} }
} }
return buffer; return buffer;

View file

@ -75,6 +75,37 @@ static void FTable_Init(void)
r_inversesawtoothtable[i] = 1.0 - t; r_inversesawtoothtable[i] = 1.0 - t;
} }
} }
typedef vec3_t mat3_t[3];
static mat3_t axisDefault={{1, 0, 0},
{0, 1, 0},
{0, 0, 1}};
static void Matrix3_Transpose (mat3_t in, mat3_t out)
{
out[0][0] = in[0][0];
out[1][1] = in[1][1];
out[2][2] = in[2][2];
out[0][1] = in[1][0];
out[0][2] = in[2][0];
out[1][0] = in[0][1];
out[1][2] = in[2][1];
out[2][0] = in[0][2];
out[2][1] = in[1][2];
}
static void Matrix3_Multiply_Vec3 (mat3_t a, vec3_t b, vec3_t product)
{
product[0] = a[0][0]*b[0] + a[0][1]*b[1] + a[0][2]*b[2];
product[1] = a[1][0]*b[0] + a[1][1]*b[1] + a[1][2]*b[2];
product[2] = a[2][0]*b[0] + a[2][1]*b[1] + a[2][2]*b[2];
}
static int Matrix3_Compare(mat3_t in, mat3_t out)
{
return !memcmp(in, out, sizeof(mat3_t));
}
/*================================================*/ /*================================================*/
typedef struct typedef struct
@ -90,8 +121,11 @@ typedef struct
texid_t curdeluxmap; texid_t curdeluxmap;
int curvertdecl; int curvertdecl;
unsigned int shaderbits; unsigned int shaderbits;
unsigned int curcull;
unsigned int lastpasscount; unsigned int lastpasscount;
texid_t curtex[MAX_TMUS];
mesh_t **meshlist; mesh_t **meshlist;
unsigned int nummeshes; unsigned int nummeshes;
@ -130,12 +164,12 @@ extern int be_maxpasses;
enum enum
{ {
D3D_VDEC_COL4B = 1<<0, D3D_VDEC_COL4B = 1<<0,
D3D_VDEC_NORMS = 1<<1, //D3D_VDEC_NORMS = 1<<1,
D3D_VDEC_ST0 = 1<<2, D3D_VDEC_ST0 = 1<<1,
D3D_VDEC_ST1 = 1<<3, D3D_VDEC_ST1 = 1<<2,
D3D_VDEC_ST2 = 1<<3, D3D_VDEC_ST2 = 1<<3,
D3D_VDEC_ST3 = 1<<3, D3D_VDEC_ST3 = 1<<4,
D3D_VDEC_MAX = 16 D3D_VDEC_MAX = 1<<5
}; };
IDirect3DVertexDeclaration9 *vertexdecls[D3D_VDEC_MAX]; IDirect3DVertexDeclaration9 *vertexdecls[D3D_VDEC_MAX];
@ -201,7 +235,7 @@ void BE_D3D_Reset(qboolean before)
elements++; elements++;
} }
if (i & D3D_VDEC_NORMS) /* if (i & D3D_VDEC_NORMS)
{ {
decl[elements].Stream = 2; decl[elements].Stream = 2;
decl[elements].Offset = 0; decl[elements].Offset = 0;
@ -227,7 +261,7 @@ void BE_D3D_Reset(qboolean before)
decl[elements].UsageIndex = 1; decl[elements].UsageIndex = 1;
elements++; elements++;
} }
*/
for (tmu = 0; tmu < MAX_TMUS; tmu++) for (tmu = 0; tmu < MAX_TMUS; tmu++)
{ {
if (i & (D3D_VDEC_ST0<<tmu)) if (i & (D3D_VDEC_ST0<<tmu))
@ -259,7 +293,8 @@ void BE_D3D_Reset(qboolean before)
static void D3DBE_ApplyShaderBits(unsigned int bits); static void D3DBE_ApplyShaderBits(unsigned int bits);
void BE_Init(void) void BE_Init(void)
{ {
be_maxpasses = 1; be_maxpasses = MAX_TMUS;
memset(&shaderstate, 0, sizeof(shaderstate));
shaderstate.curvertdecl = -1; shaderstate.curvertdecl = -1;
FTable_Init(); FTable_Init();
@ -421,48 +456,57 @@ static unsigned int allocindexbuffer(void **dest, unsigned int entries)
return offset/sizeof(index_t); return offset/sizeof(index_t);
} }
static void BindTexture(unsigned int tu, void *id)
{
if (shaderstate.curtex[tu].ptr != id)
{
shaderstate.curtex[tu].ptr = id;
IDirect3DDevice9_SetTexture (pD3DDev9, tu, id);
}
}
static void SelectPassTexture(unsigned int tu, shaderpass_t *pass) static void SelectPassTexture(unsigned int tu, shaderpass_t *pass)
{ {
switch(pass->texgen) switch(pass->texgen)
{ {
default: default:
case T_GEN_DIFFUSE: case T_GEN_DIFFUSE:
IDirect3DDevice9_SetTexture (pD3DDev9, tu, shaderstate.curtexnums->base.ptr); BindTexture(tu, shaderstate.curtexnums->base.ptr);
break; break;
case T_GEN_NORMALMAP: case T_GEN_NORMALMAP:
IDirect3DDevice9_SetTexture (pD3DDev9, tu, shaderstate.curtexnums->bump.ptr); BindTexture( tu, shaderstate.curtexnums->bump.ptr);
break; break;
case T_GEN_SPECULAR: case T_GEN_SPECULAR:
IDirect3DDevice9_SetTexture (pD3DDev9, tu, shaderstate.curtexnums->specular.ptr); BindTexture(tu, shaderstate.curtexnums->specular.ptr);
break; break;
case T_GEN_UPPEROVERLAY: case T_GEN_UPPEROVERLAY:
IDirect3DDevice9_SetTexture (pD3DDev9, tu, shaderstate.curtexnums->upperoverlay.ptr); BindTexture(tu, shaderstate.curtexnums->upperoverlay.ptr);
break; break;
case T_GEN_LOWEROVERLAY: case T_GEN_LOWEROVERLAY:
IDirect3DDevice9_SetTexture (pD3DDev9, tu, shaderstate.curtexnums->loweroverlay.ptr); BindTexture(tu, shaderstate.curtexnums->loweroverlay.ptr);
break; break;
case T_GEN_FULLBRIGHT: case T_GEN_FULLBRIGHT:
IDirect3DDevice9_SetTexture (pD3DDev9, tu, shaderstate.curtexnums->fullbright.ptr); BindTexture(tu, shaderstate.curtexnums->fullbright.ptr);
break; break;
case T_GEN_ANIMMAP: case T_GEN_ANIMMAP:
IDirect3DDevice9_SetTexture (pD3DDev9, tu, pass->anim_frames[(int)(pass->anim_fps * shaderstate.curtime) % pass->anim_numframes].ptr); BindTexture(tu, pass->anim_frames[(int)(pass->anim_fps * shaderstate.curtime) % pass->anim_numframes].ptr);
break; break;
/*fixme*/ /*fixme*/
case T_GEN_SINGLEMAP: case T_GEN_SINGLEMAP:
IDirect3DDevice9_SetTexture (pD3DDev9, tu, pass->anim_frames[0].ptr); BindTexture(tu, pass->anim_frames[0].ptr);
break; break;
case T_GEN_DELUXMAP: case T_GEN_DELUXMAP:
IDirect3DDevice9_SetTexture (pD3DDev9, tu, shaderstate.curdeluxmap.ptr); BindTexture(tu, shaderstate.curdeluxmap.ptr);
break; break;
case T_GEN_LIGHTMAP: case T_GEN_LIGHTMAP:
IDirect3DDevice9_SetTexture (pD3DDev9, tu, shaderstate.curlightmap.ptr); BindTexture(tu, shaderstate.curlightmap.ptr);
break; break;
/*case T_GEN_CURRENTRENDER: /*case T_GEN_CURRENTRENDER:
FIXME: no code to grab the current screen and convert to a texture FIXME: no code to grab the current screen and convert to a texture
break;*/ break;*/
case T_GEN_VIDEOMAP: case T_GEN_VIDEOMAP:
IDirect3DDevice9_SetTexture (pD3DDev9, tu, Media_UpdateForShader(pass->cin).ptr); BindTexture(tu, Media_UpdateForShader(pass->cin).ptr);
break; break;
} }
@ -486,43 +530,66 @@ static void SelectPassTexture(unsigned int tu, shaderpass_t *pass)
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG1, D3DTA_TEXTURE); IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG1, D3DTA_TEXTURE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG2, D3DTA_CURRENT); IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG2, D3DTA_CURRENT);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3); IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
break; break;
case GL_REPLACE: case GL_REPLACE:
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG1, D3DTA_TEXTURE); IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG1, D3DTA_TEXTURE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLOROP, D3DTOP_SELECTARG1); IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
// IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
break; break;
case GL_ADD: case GL_ADD:
if (!tu)
goto forcemod;
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG1, D3DTA_TEXTURE); IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG1, D3DTA_TEXTURE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG2, D3DTA_CURRENT); IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG2, D3DTA_CURRENT);
if (tu) IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLOROP, D3DTOP_ADD);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLOROP, D3DTOP_ADD);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAOP, D3DTOP_ADD);
break; break;
case GL_DECAL: case GL_DECAL:
if (!tu)
goto forcemod;
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG1, D3DTA_TEXTURE); IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG1, D3DTA_TEXTURE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG2, D3DTA_CURRENT); IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG2, D3DTA_CURRENT);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLOROP, D3DTOP_MODULATE); IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLOROP, D3DTOP_BLENDTEXTUREALPHA);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
break; break;
default: default:
case GL_MODULATE: case GL_MODULATE:
forcemod:
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG1, D3DTA_TEXTURE); IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG1, D3DTA_TEXTURE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG2, D3DTA_CURRENT); IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG2, D3DTA_CURRENT);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLOROP, D3DTOP_MODULATE); IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLOROP, D3DTOP_MODULATE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
break; break;
} }
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
if (tu == 0) if (tu == 0)
{ {
if (shaderstate.passsinglecolour) if (shaderstate.passsinglecolour)
{ {
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG2, D3DTA_CONSTANT); IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG2, D3DTA_CONSTANT);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG2, D3DTA_CONSTANT);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_CONSTANT, shaderstate.passcolour); IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_CONSTANT, shaderstate.passcolour);
} }
else else
{ {
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG2, D3DTA_DIFFUSE); IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
} }
} }
} }
@ -548,15 +615,27 @@ static void colourgenbyte(const shaderpass_t *pass, int cnt, const byte_vec4_t *
break; break;
case RGB_GEN_VERTEX: case RGB_GEN_VERTEX:
case RGB_GEN_EXACT_VERTEX: case RGB_GEN_EXACT_VERTEX:
while((cnt)--) if (!src)
{ {
qbyte r, g, b; while((cnt)--)
r=src[cnt][0]; {
g=src[cnt][1]; dst[cnt][0] = 255;//shaderstate.identitylighting;
b=src[cnt][2]; dst[cnt][1] = 255;//shaderstate.identitylighting;
dst[cnt][0] = b; dst[cnt][2] = 255;//shaderstate.identitylighting;
dst[cnt][1] = g; }
dst[cnt][2] = r; }
else
{
while((cnt)--)
{
qbyte r, g, b;
r=src[cnt][0];
g=src[cnt][1];
b=src[cnt][2];
dst[cnt][0] = b;
dst[cnt][1] = g;
dst[cnt][2] = r;
}
} }
break; break;
case RGB_GEN_ONE_MINUS_VERTEX: case RGB_GEN_ONE_MINUS_VERTEX:
@ -707,16 +786,14 @@ static void alphagenbyte(const shaderpass_t *pass, int cnt, const byte_vec4_t *s
} }
break; break;
/*FIXME: specular not supported (most noticable on q3dm0)*/ case ALPHA_GEN_SPECULAR:
/*case ALPHA_GEN_SPECULAR:
{ {
mat3_t axis; int i;
AngleVectors(shaderstate.curentity->angles, axis[0], axis[1], axis[2]);
VectorSubtract(r_origin, shaderstate.curentity->origin, v1); VectorSubtract(r_origin, shaderstate.curentity->origin, v1);
if (!Matrix3_Compare(axis, axisDefault)) if (!Matrix3_Compare(shaderstate.curentity->axis, axisDefault))
{ {
Matrix3_Multiply_Vec3(axis, v2, v2); Matrix3_Multiply_Vec3(shaderstate.curentity->axis, v2, v2);
} }
else else
{ {
@ -728,10 +805,10 @@ static void alphagenbyte(const shaderpass_t *pass, int cnt, const byte_vec4_t *s
VectorSubtract(v2, mesh->xyz_array[i], v1); VectorSubtract(v2, mesh->xyz_array[i], v1);
f = DotProduct(v1, mesh->normals_array[i] ) * Q_rsqrt(DotProduct(v1,v1)); f = DotProduct(v1, mesh->normals_array[i] ) * Q_rsqrt(DotProduct(v1,v1));
f = f * f * f * f * f; f = f * f * f * f * f;
dst[i][3] = bound (0.0f, f, 1.0f); dst[i][3] = bound (0.0f, (int)(f*255), 255);
} }
} }
break;*/ break;
} }
} }
@ -825,14 +902,12 @@ static unsigned int BE_GenerateColourMods(unsigned int vertcount, const shaderpa
static void tcgen_environment(float *st, unsigned int numverts, float *xyz, float *normal) static void tcgen_environment(float *st, unsigned int numverts, float *xyz, float *normal)
{ {
/*
int i; int i;
vec3_t viewer, reflected; vec3_t viewer, reflected;
float d; float d;
vec3_t rorg; vec3_t rorg;
RotateLightVector(shaderstate.curentity->axis, shaderstate.curentity->origin, r_origin, rorg); RotateLightVector(shaderstate.curentity->axis, shaderstate.curentity->origin, r_origin, rorg);
for (i = 0 ; i < numverts ; i++, xyz += 3, normal += 3, st += 2 ) for (i = 0 ; i < numverts ; i++, xyz += 3, normal += 3, st += 2 )
@ -849,7 +924,6 @@ static void tcgen_environment(float *st, unsigned int numverts, float *xyz, floa
st[0] = 0.5 + reflected[1] * 0.5; st[0] = 0.5 + reflected[1] * 0.5;
st[1] = 0.5 - reflected[2] * 0.5; st[1] = 0.5 - reflected[2] * 0.5;
} }
*/
} }
static float *tcgen(const shaderpass_t *pass, int cnt, float *dst, const mesh_t *mesh) static float *tcgen(const shaderpass_t *pass, int cnt, float *dst, const mesh_t *mesh)
@ -873,8 +947,8 @@ static float *tcgen(const shaderpass_t *pass, int cnt, float *dst, const mesh_t
tcgen_environment(dst, cnt, (float*)mesh->xyz_array, (float*)mesh->normals_array); tcgen_environment(dst, cnt, (float*)mesh->xyz_array, (float*)mesh->normals_array);
return dst; return dst;
// case TC_GEN_DOTPRODUCT: case TC_GEN_DOTPRODUCT:
// return mesh->st_array[0]; return dst;//mesh->st_array[0];
case TC_GEN_VECTOR: case TC_GEN_VECTOR:
src = mesh->xyz_array; src = mesh->xyz_array;
for (i = 0; i < cnt; i++, dst += 2) for (i = 0; i < cnt; i++, dst += 2)
@ -1004,6 +1078,246 @@ static void GenerateTCMods(const shaderpass_t *pass, float *dest)
//end texture coords //end texture coords
/*******************************************************************************************************************/ /*******************************************************************************************************************/
static void deformgen(const deformv_t *deformv, int cnt, const vecV_t *src, vecV_t *dst, const mesh_t *mesh)
{
float *table;
int j, k;
float args[4];
float deflect;
switch (deformv->type)
{
default:
case DEFORMV_NONE:
if (src != (const avec4_t*)dst)
memcpy(dst, src, sizeof(*src)*cnt);
break;
case DEFORMV_WAVE:
if (!mesh->normals_array)
{
if (src != (const avec4_t*)dst)
memcpy(dst, src, sizeof(*src)*cnt);
return;
}
args[0] = deformv->func.args[0];
args[1] = deformv->func.args[1];
args[3] = deformv->func.args[2] + deformv->func.args[3] * shaderstate.curtime;
table = FTableForFunc(deformv->func.type);
for ( j = 0; j < cnt; j++ )
{
deflect = deformv->args[0] * (src[j][0]+src[j][1]+src[j][2]) + args[3];
deflect = FTABLE_EVALUATE(table, deflect) * args[1] + args[0];
// Deflect vertex along its normal by wave amount
VectorMA(src[j], deflect, mesh->normals_array[j], dst[j]);
}
break;
case DEFORMV_NORMAL:
//normal does not actually move the verts, but it does change the normals array
//we don't currently support that.
if (src != (const avec4_t*)dst)
memcpy(dst, src, sizeof(*src)*cnt);
/*
args[0] = deformv->args[1] * shaderstate.curtime;
for ( j = 0; j < cnt; j++ )
{
args[1] = normalsArray[j][2] * args[0];
deflect = deformv->args[0] * R_FastSin(args[1]);
normalsArray[j][0] *= deflect;
deflect = deformv->args[0] * R_FastSin(args[1] + 0.25);
normalsArray[j][1] *= deflect;
VectorNormalizeFast(normalsArray[j]);
}
*/ break;
case DEFORMV_MOVE:
table = FTableForFunc(deformv->func.type);
deflect = deformv->func.args[2] + shaderstate.curtime * deformv->func.args[3];
deflect = FTABLE_EVALUATE(table, deflect) * deformv->func.args[1] + deformv->func.args[0];
for ( j = 0; j < cnt; j++ )
VectorMA(src[j], deflect, deformv->args, dst[j]);
break;
case DEFORMV_BULGE:
args[0] = deformv->args[0]/(2*M_PI);
args[1] = deformv->args[1];
args[2] = shaderstate.curtime * deformv->args[2]/(2*M_PI);
for (j = 0; j < cnt; j++)
{
deflect = R_FastSin(mesh->st_array[j][0]*args[0] + args[2])*args[1];
dst[j][0] = src[j][0]+deflect*mesh->normals_array[j][0];
dst[j][1] = src[j][1]+deflect*mesh->normals_array[j][1];
dst[j][2] = src[j][2]+deflect*mesh->normals_array[j][2];
}
break;
case DEFORMV_AUTOSPRITE:
if (mesh->numindexes < 6)
break;
for (j = 0; j < cnt-3; j+=4, src+=4, dst+=4)
{
vec3_t mid, d;
float radius;
mid[0] = 0.25*(src[0][0] + src[1][0] + src[2][0] + src[3][0]);
mid[1] = 0.25*(src[0][1] + src[1][1] + src[2][1] + src[3][1]);
mid[2] = 0.25*(src[0][2] + src[1][2] + src[2][2] + src[3][2]);
VectorSubtract(src[0], mid, d);
radius = 2*VectorLength(d);
for (k = 0; k < 4; k++)
{
dst[k][0] = mid[0] + radius*((mesh->st_array[k][0]-0.5)*r_refdef.m_view[0+0]-(mesh->st_array[k][1]-0.5)*r_refdef.m_view[0+1]);
dst[k][1] = mid[1] + radius*((mesh->st_array[k][0]-0.5)*r_refdef.m_view[4+0]-(mesh->st_array[k][1]-0.5)*r_refdef.m_view[4+1]);
dst[k][2] = mid[2] + radius*((mesh->st_array[k][0]-0.5)*r_refdef.m_view[8+0]-(mesh->st_array[k][1]-0.5)*r_refdef.m_view[8+1]);
}
}
break;
case DEFORMV_AUTOSPRITE2:
if (mesh->numindexes < 6)
break;
for (k = 0; k < mesh->numindexes; k += 6)
{
int long_axis, short_axis;
vec3_t axis;
float len[3];
mat3_t m0, m1, m2, result;
float *quad[4];
vec3_t rot_centre, tv;
quad[0] = (float *)(dst + mesh->indexes[k+0]);
quad[1] = (float *)(dst + mesh->indexes[k+1]);
quad[2] = (float *)(dst + mesh->indexes[k+2]);
for (j = 2; j >= 0; j--)
{
quad[3] = (float *)(dst + mesh->indexes[k+3+j]);
if (!VectorEquals (quad[3], quad[0]) &&
!VectorEquals (quad[3], quad[1]) &&
!VectorEquals (quad[3], quad[2]))
{
break;
}
}
// build a matrix were the longest axis of the billboard is the Y-Axis
VectorSubtract(quad[1], quad[0], m0[0]);
VectorSubtract(quad[2], quad[0], m0[1]);
VectorSubtract(quad[2], quad[1], m0[2]);
len[0] = DotProduct(m0[0], m0[0]);
len[1] = DotProduct(m0[1], m0[1]);
len[2] = DotProduct(m0[2], m0[2]);
if ((len[2] > len[1]) && (len[2] > len[0]))
{
if (len[1] > len[0])
{
long_axis = 1;
short_axis = 0;
}
else
{
long_axis = 0;
short_axis = 1;
}
}
else if ((len[1] > len[2]) && (len[1] > len[0]))
{
if (len[2] > len[0])
{
long_axis = 2;
short_axis = 0;
}
else
{
long_axis = 0;
short_axis = 2;
}
}
else //if ( (len[0] > len[1]) && (len[0] > len[2]) )
{
if (len[2] > len[1])
{
long_axis = 2;
short_axis = 1;
}
else
{
long_axis = 1;
short_axis = 2;
}
}
if (DotProduct(m0[long_axis], m0[short_axis]))
{
VectorNormalize2(m0[long_axis], axis);
VectorCopy(axis, m0[1]);
if (axis[0] || axis[1])
{
VectorVectors(m0[1], m0[2], m0[0]);
}
else
{
VectorVectors(m0[1], m0[0], m0[2]);
}
}
else
{
VectorNormalize2(m0[long_axis], axis);
VectorNormalize2(m0[short_axis], m0[0]);
VectorCopy(axis, m0[1]);
CrossProduct(m0[0], m0[1], m0[2]);
}
for (j = 0; j < 3; j++)
rot_centre[j] = (quad[0][j] + quad[1][j] + quad[2][j] + quad[3][j]) * 0.25;
if (shaderstate.curentity)
{
VectorAdd(shaderstate.curentity->origin, rot_centre, tv);
}
else
{
VectorCopy(rot_centre, tv);
}
VectorSubtract(r_origin, tv, tv);
// filter any longest-axis-parts off the camera-direction
deflect = -DotProduct(tv, axis);
VectorMA(tv, deflect, axis, m1[2]);
VectorNormalizeFast(m1[2]);
VectorCopy(axis, m1[1]);
CrossProduct(m1[1], m1[2], m1[0]);
Matrix3_Transpose(m1, m2);
Matrix3_Multiply(m2, m0, result);
for (j = 0; j < 4; j++)
{
VectorSubtract(quad[j], rot_centre, tv);
Matrix3_Multiply_Vec3(result, tv, quad[j]);
VectorAdd(rot_centre, quad[j], quad[j]);
}
}
break;
// case DEFORMV_PROJECTION_SHADOW:
// break;
}
}
/*does not do the draw call, does not consider indicies (except for billboard generation) */ /*does not do the draw call, does not consider indicies (except for billboard generation) */
static qboolean BE_DrawMeshChain_SetupPass(shaderpass_t *pass, unsigned int vertcount) static qboolean BE_DrawMeshChain_SetupPass(shaderpass_t *pass, unsigned int vertcount)
{ {
@ -1025,7 +1339,7 @@ static qboolean BE_DrawMeshChain_SetupPass(shaderpass_t *pass, unsigned int vert
break; break;
} }
if (i == lastpass) if (i == lastpass)
return lastpass; return false;
/*all meshes in a chain must have the same features*/ /*all meshes in a chain must have the same features*/
@ -1054,13 +1368,13 @@ static qboolean BE_DrawMeshChain_SetupPass(shaderpass_t *pass, unsigned int vert
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, 5+tmu, shaderstate.dynst_buff[tmu], shaderstate.dynst_offs[tmu] - vertcount*sizeof(vec2_t), sizeof(vec2_t))); d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, 5+tmu, shaderstate.dynst_buff[tmu], shaderstate.dynst_offs[tmu] - vertcount*sizeof(vec2_t), sizeof(vec2_t)));
tmu++; tmu++;
} }
if (!tmu)
return false;
/*deactivate any extras*/ /*deactivate any extras*/
for (; tmu < shaderstate.lastpasscount; tmu++) for (; tmu < shaderstate.lastpasscount; )
{ {
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, 5+tmu, NULL, 0, 0)); d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, 5+tmu, NULL, 0, 0));
BindTexture(tmu, NULL);
d3dcheck(IDirect3DDevice9_SetTextureStageState(pD3DDev9, tmu, D3DTSS_COLOROP, D3DTOP_DISABLE)); d3dcheck(IDirect3DDevice9_SetTextureStageState(pD3DDev9, tmu, D3DTSS_COLOROP, D3DTOP_DISABLE));
tmu++;
} }
shaderstate.lastpasscount = tmu; shaderstate.lastpasscount = tmu;
@ -1089,6 +1403,17 @@ static void BE_DrawMeshChain_Internal(void)
unsigned int passno = 0; unsigned int passno = 0;
shaderpass_t *pass = shaderstate.curshader->passes; shaderpass_t *pass = shaderstate.curshader->passes;
if (shaderstate.curcull != (shaderstate.curshader->flags & (SHADER_CULL_FRONT | SHADER_CULL_BACK)))
{
shaderstate.curcull = shaderstate.curshader->flags & (SHADER_CULL_FRONT | SHADER_CULL_BACK);
if (shaderstate.curcull & SHADER_CULL_FRONT)
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_CULLMODE, D3DCULL_CCW);
else if (shaderstate.curcull & SHADER_CULL_BACK)
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_CULLMODE, D3DCULL_CW);
else
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_CULLMODE, D3DCULL_NONE);
}
for (mno = 0, vertcount = 0, idxcount = 0; mno < shaderstate.nummeshes; mno++) for (mno = 0, vertcount = 0, idxcount = 0; mno < shaderstate.nummeshes; mno++)
{ {
m = shaderstate.meshlist[mno]; m = shaderstate.meshlist[mno];
@ -1100,9 +1425,13 @@ static void BE_DrawMeshChain_Internal(void)
allocvertexbuffer(shaderstate.dynxyz_buff, shaderstate.dynxyz_size, &shaderstate.dynxyz_offs, &map, vertcount*sizeof(vecV_t)); allocvertexbuffer(shaderstate.dynxyz_buff, shaderstate.dynxyz_size, &shaderstate.dynxyz_offs, &map, vertcount*sizeof(vecV_t));
for (mno = 0, vertcount = 0; mno < shaderstate.nummeshes; mno++) for (mno = 0, vertcount = 0; mno < shaderstate.nummeshes; mno++)
{ {
vecV_t *dest = (vecV_t*)((char*)map+vertcount*sizeof(vecV_t));
m = shaderstate.meshlist[mno]; m = shaderstate.meshlist[mno];
/*fixme: no tcgen*/ deformgen(&shaderstate.curshader->deforms[0], m->numvertexes, m->xyz_array, dest, m);
memcpy((char*)map+vertcount*sizeof(vecV_t), m->xyz_array, m->numvertexes*sizeof(vecV_t)); for (i = 1; i < shaderstate.curshader->numdeforms; i++)
{
deformgen(&shaderstate.curshader->deforms[i], m->numvertexes, dest, dest, m);
}
vertcount += m->numvertexes; vertcount += m->numvertexes;
} }
d3dcheck(IDirect3DVertexBuffer9_Unlock(shaderstate.dynxyz_buff)); d3dcheck(IDirect3DVertexBuffer9_Unlock(shaderstate.dynxyz_buff));
@ -1476,6 +1805,9 @@ static void BE_SubmitBatch(batch_t *batch)
shaderstate.nummeshes = batch->meshes - batch->firstmesh; shaderstate.nummeshes = batch->meshes - batch->firstmesh;
if (!shaderstate.nummeshes) if (!shaderstate.nummeshes)
return; return;
//FIXME: Why does this seem to work in GL?
if (batch->shader->flags & SHADER_FLARE)
return;
if (shaderstate.curentity != batch->ent) if (shaderstate.curentity != batch->ent)
{ {
shaderstate.curentity = batch->ent; shaderstate.curentity = batch->ent;
@ -1523,6 +1855,127 @@ qboolean BE_ShouldDraw(entity_t *e)
return true; return true;
} }
#ifdef Q3CLIENT
//q3 lightning gun
static void R_DrawLightning(entity_t *e)
{
vec3_t v;
vec3_t dir, cr;
float scale = e->scale;
float length;
vecV_t points[4];
vec2_t texcoords[4] = {{0, 0}, {0, 1}, {1, 1}, {1, 0}};
static index_t indexarray[6] = {0, 1, 2, 0, 2, 3};
mesh_t mesh;
if (!e->forcedshader)
return;
if (!scale)
scale = 10;
VectorSubtract(e->origin, e->oldorigin, dir);
length = Length(dir);
//this seems to be about right.
texcoords[2][0] = length/128;
texcoords[3][0] = length/128;
VectorSubtract(r_refdef.vieworg, e->origin, v);
CrossProduct(v, dir, cr);
VectorNormalize(cr);
VectorMA(e->origin, -scale/2, cr, points[0]);
VectorMA(e->origin, scale/2, cr, points[1]);
VectorSubtract(r_refdef.vieworg, e->oldorigin, v);
CrossProduct(v, dir, cr);
VectorNormalize(cr);
VectorMA(e->oldorigin, scale/2, cr, points[2]);
VectorMA(e->oldorigin, -scale/2, cr, points[3]);
memset(&mesh, 0, sizeof(mesh));
mesh.vbofirstelement = 0;
mesh.vbofirstvert = 0;
mesh.xyz_array = points;
mesh.indexes = indexarray;
mesh.numindexes = sizeof(indexarray)/sizeof(indexarray[0]);
mesh.colors4f_array = NULL;
mesh.lmst_array = NULL;
mesh.normals_array = NULL;
mesh.numvertexes = 4;
mesh.st_array = texcoords;
BE_DrawMesh_Single(e->forcedshader, &mesh, NULL, NULL);
}
//q3 railgun beam
static void R_DrawRailCore(entity_t *e)
{
vec3_t v;
vec3_t dir, cr;
float scale = e->scale;
float length;
mesh_t mesh;
vecV_t points[4];
vec2_t texcoords[4] = {{0, 0}, {0, 1}, {1, 1}, {1, 0}};
static index_t indexarray[6] = {0, 1, 2, 0, 2, 3};
vec4_t colors[4];
if (!e->forcedshader)
return;
if (!scale)
scale = 10;
VectorSubtract(e->origin, e->oldorigin, dir);
length = Length(dir);
//this seems to be about right.
texcoords[2][0] = length/128;
texcoords[3][0] = length/128;
VectorSubtract(r_refdef.vieworg, e->origin, v);
CrossProduct(v, dir, cr);
VectorNormalize(cr);
VectorMA(e->origin, -scale/2, cr, points[0]);
VectorMA(e->origin, scale/2, cr, points[1]);
VectorSubtract(r_refdef.vieworg, e->oldorigin, v);
CrossProduct(v, dir, cr);
VectorNormalize(cr);
VectorMA(e->oldorigin, scale/2, cr, points[2]);
VectorMA(e->oldorigin, -scale/2, cr, points[3]);
Vector4Copy(e->shaderRGBAf, colors[0]);
Vector4Copy(e->shaderRGBAf, colors[1]);
Vector4Copy(e->shaderRGBAf, colors[2]);
Vector4Copy(e->shaderRGBAf, colors[3]);
memset(&mesh, 0, sizeof(mesh));
mesh.vbofirstelement = 0;
mesh.vbofirstvert = 0;
mesh.xyz_array = points;
mesh.indexes = indexarray;
mesh.numindexes = sizeof(indexarray)/sizeof(indexarray[0]);
mesh.colors4f_array = (vec4_t*)colors;
mesh.lmst_array = NULL;
mesh.normals_array = NULL;
mesh.numvertexes = 4;
mesh.st_array = texcoords;
BE_DrawMesh_Single(e->forcedshader, &mesh, NULL, NULL);
}
#endif
static void BE_GenModelBatches(batch_t **batches) static void BE_GenModelBatches(batch_t **batches)
{ {
int i; int i;
@ -1539,23 +1992,52 @@ static void BE_GenModelBatches(batch_t **batches)
for (i=0 ; i<cl_numvisedicts ; i++) for (i=0 ; i<cl_numvisedicts ; i++)
{ {
ent = &cl_visedicts[i]; ent = &cl_visedicts[i];
if (!ent->model)
continue;
if (ent->model->needload)
continue;
if (!BE_ShouldDraw(ent)) if (!BE_ShouldDraw(ent))
continue; continue;
switch(ent->model->type)
switch(ent->rtype)
{ {
case mod_brush: case RT_MODEL:
if (r_drawentities.ival == 2) default:
if (!ent->model)
continue; continue;
Surf_GenBrushBatches(batches, ent); if (ent->model->needload)
continue;
switch(ent->model->type)
{
case mod_brush:
if (r_drawentities.ival == 2)
continue;
Surf_GenBrushBatches(batches, ent);
break;
case mod_alias:
if (r_drawentities.ival == 3)
continue;
R_GAlias_GenerateBatches(ent, batches);
break;
}
break; break;
case mod_alias: case RT_SPRITE:
if (r_drawentities.ival == 3) //RQ_AddDistReorder(GLR_DrawSprite, currententity, NULL, currententity->origin);
continue; break;
R_GAlias_GenerateBatches(ent, batches);
#ifdef Q3CLIENT
case RT_BEAM:
case RT_RAIL_RINGS:
case RT_LIGHTNING:
R_DrawLightning(ent);
continue;
case RT_RAIL_CORE:
R_DrawRailCore(ent);
continue;
#endif
case RT_POLY:
/*not implemented*/
break;
case RT_PORTALSURFACE:
/*nothing*/
break; break;
} }
} }
@ -1631,22 +2113,31 @@ void BE_DrawWorld (qbyte *vis)
shaderstate.curtime = realtime; shaderstate.curtime = realtime;
BE_UploadLightmaps(false); if (vis)
{
BE_UploadLightmaps(false);
//make sure the world draws correctly //make sure the world draws correctly
r_worldentity.shaderRGBAf[0] = 1; r_worldentity.shaderRGBAf[0] = 1;
r_worldentity.shaderRGBAf[1] = 1; r_worldentity.shaderRGBAf[1] = 1;
r_worldentity.shaderRGBAf[2] = 1; r_worldentity.shaderRGBAf[2] = 1;
r_worldentity.shaderRGBAf[3] = 1; r_worldentity.shaderRGBAf[3] = 1;
r_worldentity.axis[0][0] = 1; r_worldentity.axis[0][0] = 1;
r_worldentity.axis[1][1] = 1; r_worldentity.axis[1][1] = 1;
r_worldentity.axis[2][2] = 1; r_worldentity.axis[2][2] = 1;
BE_SelectMode(BEM_STANDARD, 0); BE_SelectMode(BEM_STANDARD, 0);
RSpeedRemark(); RSpeedRemark();
BE_SubmitMeshes(true, batches); BE_SubmitMeshes(true, batches);
RSpeedEnd(RSPEED_WORLD); RSpeedEnd(RSPEED_WORLD);
}
else
{
RSpeedRemark();
BE_SubmitMeshes(false, batches);
RSpeedEnd(RSPEED_DRAWENTITIES);
}
BE_RotateForEntity(&r_worldentity, NULL); BE_RotateForEntity(&r_worldentity, NULL);
} }

View file

@ -439,16 +439,140 @@ typedef struct tagMONITORINFO
} MONITORINFO, *LPMONITORINFO; } MONITORINFO, *LPMONITORINFO;
#endif #endif
static void initD3D9(HWND hWnd, rendererstate_t *info) static qboolean initD3D9Device(HWND hWnd, rendererstate_t *info, unsigned int devno, unsigned int devtype)
{ {
int i;
int numadaptors;
int err; int err;
RECT rect; RECT rect;
D3DADAPTER_IDENTIFIER9 inf; D3DADAPTER_IDENTIFIER9 inf;
D3DCAPS9 caps; D3DCAPS9 caps;
unsigned int cflags; unsigned int cflags;
memset(&inf, 0, sizeof(inf));
if (FAILED(IDirect3D9_GetAdapterIdentifier(pD3D, devno, 0, &inf)))
return false;
if (FAILED(IDirect3D9_GetDeviceCaps(pD3D, devno, devtype, &caps)))
return false;
memset(&d3dpp, 0, sizeof(d3dpp)); // clear out the struct for use
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; // discard old frames
d3dpp.hDeviceWindow = hWnd; // set the window to be used by Direct3D
d3dpp.BackBufferWidth = info->width;
d3dpp.BackBufferHeight = info->height;
d3dpp.MultiSampleType = info->multisample;
d3dpp.BackBufferCount = 1;
d3dpp.FullScreen_RefreshRateInHz = info->fullscreen?info->rate:0; //don't pass a rate if not fullscreen, d3d doesn't like it.
d3dpp.Windowed = !info->fullscreen;
d3dpp.EnableAutoDepthStencil = true;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
if (info->fullscreen)
{
if (info->bpp == 16)
d3dpp.BackBufferFormat = D3DFMT_R5G6B5;
else
d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
}
switch(info->wait)
{
default:
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
break;
case 0:
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
break;
case 1:
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
break;
case 2:
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_TWO;
break;
case 3:
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_THREE;
break;
case 4:
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_FOUR;
break;
}
cflags = D3DCREATE_FPU_PRESERVE;
if ((caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) && (caps.DevCaps & D3DDEVCAPS_PUREDEVICE))
cflags |= D3DCREATE_HARDWARE_VERTEXPROCESSING;
else
cflags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
//cflags |= D3DCREATE_DISABLE_DRIVER_MANAGEMENT;
pD3DDev9 = NULL;
// create a device class using this information and information from the d3dpp stuct
err = IDirect3D9_CreateDevice(pD3D,
devno,
devtype,
hWnd,
cflags,
&d3dpp,
&pD3DDev9);
if (pD3DDev9)
{
HMONITOR hm;
MONITORINFO mi;
char *s;
for (s = inf.Description + strlen(inf.Description)-1; s >= inf.Description && *s <= ' '; s--)
*s = 0;
Con_Printf("D3D9: Using device %s\n", inf.Description);
vid.numpages = d3dpp.BackBufferCount;
if (d3dpp.Windowed) //fullscreen we get positioned automagically.
{ //windowed, we get positioned at 0,0... which is often going to be on the wrong screen
//the user can figure it out from here
static HANDLE huser32;
BOOL (WINAPI *pGetMonitorInfoA)(HMONITOR hMonitor, LPMONITORINFO lpmi);
if (!huser32)
huser32 = LoadLibrary("user32.dll");
if (!huser32)
return false;
pGetMonitorInfoA = (void*)GetProcAddress(huser32, "GetMonitorInfoA");
if (!pGetMonitorInfoA)
return false;
hm = IDirect3D9_GetAdapterMonitor(pD3D, devno);
memset(&mi, 0, sizeof(mi));
mi.cbSize = sizeof(mi);
pGetMonitorInfoA(hm, &mi);
rect.left = rect.top = 0;
rect.right = d3dpp.BackBufferWidth;
rect.bottom = d3dpp.BackBufferHeight;
AdjustWindowRectEx(&rect, WS_OVERLAPPEDWINDOW, FALSE, 0);
MoveWindow(d3dpp.hDeviceWindow, mi.rcWork.left, mi.rcWork.top, rect.right-rect.left, rect.bottom-rect.top, false);
}
return true; //successful
}
else
{
char *s;
switch(err)
{
default: s = "Unkown error"; break;
case D3DERR_DEVICELOST: s = "Device lost"; break;
case D3DERR_INVALIDCALL: s = "Invalid call"; break;
case D3DERR_NOTAVAILABLE: s = "Not available"; break;
case D3DERR_OUTOFVIDEOMEMORY: s = "Out of video memory"; break;
}
Con_Printf("IDirect3D9_CreateDevice failed: %s.\n", s);
}
return false;
}
static void initD3D9(HWND hWnd, rendererstate_t *info)
{
int i;
int numadaptors;
int err;
D3DADAPTER_IDENTIFIER9 inf;
static HMODULE d3d9dll; static HMODULE d3d9dll;
LPDIRECT3D9 (WINAPI *pDirect3DCreate9) (int version); LPDIRECT3D9 (WINAPI *pDirect3DCreate9) (int version);
@ -473,124 +597,17 @@ static void initD3D9(HWND hWnd, rendererstate_t *info)
numadaptors = IDirect3D9_GetAdapterCount(pD3D); numadaptors = IDirect3D9_GetAdapterCount(pD3D);
for (i = 0; i < numadaptors; i++) for (i = 0; i < numadaptors; i++)
{ //try each adaptor in turn until we get one that actually works { //try each adaptor in turn until we get one that actually works
if (FAILED(IDirect3D9_GetDeviceCaps(pD3D, i, D3DDEVTYPE_HAL, &caps)))
continue;
memset(&d3dpp, 0, sizeof(d3dpp)); // clear out the struct for use
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; // discard old frames
d3dpp.hDeviceWindow = hWnd; // set the window to be used by Direct3D
d3dpp.BackBufferWidth = info->width;
d3dpp.BackBufferHeight = info->height;
d3dpp.MultiSampleType = info->multisample;
d3dpp.BackBufferCount = 1;
d3dpp.FullScreen_RefreshRateInHz = info->fullscreen?info->rate:0; //don't pass a rate if not fullscreen, d3d doesn't like it.
d3dpp.Windowed = !info->fullscreen;
d3dpp.EnableAutoDepthStencil = true;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
if (info->fullscreen)
{
if (info->bpp == 16)
d3dpp.BackBufferFormat = D3DFMT_R5G6B5;
else
d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
}
switch(info->wait)
{
default:
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
break;
case 0:
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
break;
case 1:
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
break;
case 2:
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_TWO;
break;
case 3:
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_THREE;
break;
case 4:
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_FOUR;
break;
}
cflags = D3DCREATE_FPU_PRESERVE;
if ((caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) && (caps.DevCaps & D3DDEVCAPS_PUREDEVICE))
cflags |= D3DCREATE_HARDWARE_VERTEXPROCESSING;
else
cflags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
//cflags |= D3DCREATE_DISABLE_DRIVER_MANAGEMENT;
memset(&inf, 0, sizeof(inf)); memset(&inf, 0, sizeof(inf));
err = IDirect3D9_GetAdapterIdentifier(pD3D, i, 0, &inf); err = IDirect3D9_GetAdapterIdentifier(pD3D, i, 0, &inf);
if (strstr(inf.Description, "PerfHUD"))
pD3DDev9 = NULL; if (initD3D9Device(hWnd, info, i, D3DDEVTYPE_REF))
// create a device class using this information and information from the d3dpp stuct return;
err = IDirect3D9_CreateDevice(pD3D, }
i, for (i = 0; i < numadaptors; i++)
D3DDEVTYPE_HAL, { //try each adaptor in turn until we get one that actually works
hWnd, if (initD3D9Device(hWnd, info, i, D3DDEVTYPE_HAL))
cflags, return;
&d3dpp,
&pD3DDev9);
if (pD3DDev9)
{
HMONITOR hm;
MONITORINFO mi;
char *s;
for (s = inf.Description + strlen(inf.Description)-1; s >= inf.Description && *s <= ' '; s--)
*s = 0;
Con_Printf("D3D9: Using device %s\n", inf.Description);
vid.numpages = d3dpp.BackBufferCount;
if (d3dpp.Windowed) //fullscreen we get positioned automagically.
{ //windowed, we get positioned at 0,0... which is often going to be on the wrong screen
//the user can figure it out from here
static HANDLE huser32;
BOOL (WINAPI *pGetMonitorInfoA)(HMONITOR hMonitor, LPMONITORINFO lpmi);
if (!huser32)
huser32 = LoadLibrary("user32.dll");
if (!huser32)
return;
pGetMonitorInfoA = (void*)GetProcAddress(huser32, "GetMonitorInfoA");
if (!pGetMonitorInfoA)
return;
hm = IDirect3D9_GetAdapterMonitor(pD3D, i);
memset(&mi, 0, sizeof(mi));
mi.cbSize = sizeof(mi);
pGetMonitorInfoA(hm, &mi);
rect.left = rect.top = 0;
rect.right = d3dpp.BackBufferWidth;
rect.bottom = d3dpp.BackBufferHeight;
AdjustWindowRectEx(&rect, WS_OVERLAPPEDWINDOW, FALSE, 0);
MoveWindow(d3dpp.hDeviceWindow, mi.rcWork.left, mi.rcWork.top, rect.right-rect.left, rect.bottom-rect.top, false);
}
return; //successful
}
else
{
char *s;
switch(err)
{
default: s = "Unkown error"; break;
case D3DERR_DEVICELOST: s = "Device lost"; break;
case D3DERR_INVALIDCALL: s = "Invalid call"; break;
case D3DERR_NOTAVAILABLE: s = "Not available"; break;
case D3DERR_OUTOFVIDEOMEMORY: s = "Out of video memory"; break;
}
Con_Printf("IDirect3D9_CreateDevice failed: %s.\n", s);
}
} }
return;
} }
static qboolean D3D9_VID_Init(rendererstate_t *info, unsigned char *palette) static qboolean D3D9_VID_Init(rendererstate_t *info, unsigned char *palette)
@ -728,16 +745,6 @@ static int (D3D9_R_LightPoint) (vec3_t point)
return 0; return 0;
} }
static void (D3D9_R_PushDlights) (void)
{
}
static void (D3D9_R_AddStain) (vec3_t org, float red, float green, float blue, float radius)
{
}
static void (D3D9_R_LessenStains) (void)
{
}
static void (D3D9_VID_DeInit) (void) static void (D3D9_VID_DeInit) (void)
{ {
/*final shutdown, kill the video stuff*/ /*final shutdown, kill the video stuff*/
@ -794,18 +801,6 @@ void D3D9_Set2D (void)
Matrix4_Identity(m); Matrix4_Identity(m);
IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_VIEW, (D3DMATRIX*)m); IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_VIEW, (D3DMATRIX*)m);
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_CULLMODE, D3DCULL_CCW);
IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
IDirect3DDevice9_SetSamplerState(pD3DDev9, 1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
IDirect3DDevice9_SetSamplerState(pD3DDev9, 1, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
IDirect3DDevice9_SetSamplerState(pD3DDev9, 1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
vport.X = 0; vport.X = 0;
vport.Y = 0; vport.Y = 0;
vport.Width = vid.pixelwidth; vport.Width = vid.pixelwidth;
@ -944,9 +939,6 @@ static void (D3D9_SCR_UpdateScreen) (void)
// R2D_BrightenScreen(); // R2D_BrightenScreen();
IDirect3DDevice9_EndScene(pD3DDev9); IDirect3DDevice9_EndScene(pD3DDev9);
IDirect3DDevice9_Present(pD3DDev9, NULL, NULL, NULL, NULL); IDirect3DDevice9_Present(pD3DDev9, NULL, NULL, NULL, NULL);
// pD3DDev->lpVtbl->BeginScene(pD3DDev);
RSpeedEnd(RSPEED_TOTALREFRESH); RSpeedEnd(RSPEED_TOTALREFRESH);
return; return;
} }
@ -1142,9 +1134,13 @@ static void (D3D9_R_RenderView) (void)
D3D9_SetupViewPort(); D3D9_SetupViewPort();
d3d9error(IDirect3DDevice9_Clear(pD3DDev9, 0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1, 0)); d3d9error(IDirect3DDevice9_Clear(pD3DDev9, 0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1, 0));
R_SetFrustum (r_refdef.m_projection, r_refdef.m_view); R_SetFrustum (r_refdef.m_projection, r_refdef.m_view);
RQ_BeginFrame();
Surf_DrawWorld();
if (!(r_refdef.flags & Q2RDF_NOWORLDMODEL)) if (!(r_refdef.flags & Q2RDF_NOWORLDMODEL))
Surf_DrawWorld(); {
P_DrawParticles (); if (cl.worldmodel)
P_DrawParticles ();
}
RQ_RenderBatchClear(); RQ_RenderBatchClear();
} }
@ -1217,9 +1213,8 @@ rendererinfo_t d3drendererinfo =
D3D9_R_PreNewMap, D3D9_R_PreNewMap,
D3D9_R_LightPoint, D3D9_R_LightPoint,
D3D9_R_PushDlights, Surf_AddStain,
D3D9_R_AddStain, Surf_LessenStains,
D3D9_R_LessenStains,
RMod_Init, RMod_Init,
RMod_ClearAll, RMod_ClearAll,

View file

@ -813,8 +813,8 @@ static qboolean R_CalcModelLighting(entity_t *e, model_t *clmodel)
if (fb >= 1 && r_fb_models.value) if (fb >= 1 && r_fb_models.value)
{ {
ambientlight[0] = ambientlight[1] = ambientlight[2] = 4096; ambientlight[0] = ambientlight[1] = ambientlight[2] = 1;
shadelight[0] = shadelight[1] = shadelight[2] = 4096; shadelight[0] = shadelight[1] = shadelight[2] = 1;
return true; return true;
} }
else else

View file

@ -2213,9 +2213,13 @@ static void BE_RenderMeshProgram(const shader_t *shader, const shaderpass_t *pas
} }
break; break;
case SP_CONSTI:
case SP_TEXTURE: case SP_TEXTURE:
qglUniform1iARB(s->progparm[i].handle[perm], s->progparm[i].ival); qglUniform1iARB(s->progparm[i].handle[perm], s->progparm[i].ival);
break; break;
case SP_CONSTF:
qglUniform1fARB(s->progparm[i].handle[perm], s->progparm[i].fval);
break;
case SP_CVARI: case SP_CVARI:
qglUniform1iARB(s->progparm[i].handle[perm], ((cvar_t*)s->progparm[i].pval)->ival); qglUniform1iARB(s->progparm[i].handle[perm], ((cvar_t*)s->progparm[i].pval)->ival);
break; break;

View file

@ -248,6 +248,7 @@ void Font_Init(void)
fontplanes.shader = R_RegisterShader("ftefont", fontplanes.shader = R_RegisterShader("ftefont",
"{\n" "{\n"
"nomipmaps\n"
"{\n" "{\n"
"map $diffuse\n" "map $diffuse\n"
"rgbgen const\n" "rgbgen const\n"
@ -259,6 +260,7 @@ void Font_Init(void)
fontplanes.backshader = R_RegisterShader("ftefontback", fontplanes.backshader = R_RegisterShader("ftefontback",
"{\n" "{\n"
"nomipmaps\n"
"{\n" "{\n"
"map $whiteimage\n" "map $whiteimage\n"
"rgbgen const\n" "rgbgen const\n"

View file

@ -2659,7 +2659,6 @@ float RadiusFromBounds (vec3_t mins, vec3_t maxs);
//combination of R_AddDynamicLights and R_MarkLights //combination of R_AddDynamicLights and R_MarkLights
static void Q1BSP_StainNode (mnode_t *node, float *parms) static void Q1BSP_StainNode (mnode_t *node, float *parms)
{ {
#ifdef GLQUAKE
mplane_t *splitplane; mplane_t *splitplane;
float dist; float dist;
msurface_t *surf; msurface_t *surf;
@ -2693,7 +2692,6 @@ static void Q1BSP_StainNode (mnode_t *node, float *parms)
Q1BSP_StainNode (node->children[0], parms); Q1BSP_StainNode (node->children[0], parms);
Q1BSP_StainNode (node->children[1], parms); Q1BSP_StainNode (node->children[1], parms);
#endif
} }
void RMod_FixupNodeMinsMaxs (mnode_t *node, mnode_t *parent) void RMod_FixupNodeMinsMaxs (mnode_t *node, mnode_t *parent)

View file

@ -418,7 +418,7 @@ void GLR_MarkQ3Lights (dlight_t *light, int bit, mnode_t *node)
R_PushDlights R_PushDlights
============= =============
*/ */
void GLR_PushDlights (void) void R_PushDlights (void)
{ {
int i; int i;
dlight_t *l; dlight_t *l;

View file

@ -1118,6 +1118,8 @@ void R_RenderScene (void)
TRACE(("dbg: calling R_SetFrustrum\n")); TRACE(("dbg: calling R_SetFrustrum\n"));
R_SetFrustum (r_refdef.m_projection, r_refdef.m_view); R_SetFrustum (r_refdef.m_projection, r_refdef.m_view);
RQ_BeginFrame();
if (!(r_refdef.flags & Q2RDF_NOWORLDMODEL)) if (!(r_refdef.flags & Q2RDF_NOWORLDMODEL))
{ {
TRACE(("dbg: calling R_DrawWorld\n")); TRACE(("dbg: calling R_DrawWorld\n"));
@ -1128,8 +1130,6 @@ void R_RenderScene (void)
S_ExtraUpdate (); // don't let sound get messed up if going slow S_ExtraUpdate (); // don't let sound get messed up if going slow
RQ_BeginFrame();
TRACE(("dbg: calling GLR_DrawEntitiesOnList\n")); TRACE(("dbg: calling GLR_DrawEntitiesOnList\n"));
GLR_DrawEntitiesOnList (); GLR_DrawEntitiesOnList ();

View file

@ -31,6 +31,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <ctype.h> #include <ctype.h>
#include <GL/gl.h>
#include "glsupp.h"
extern texid_t missing_texture; extern texid_t missing_texture;
@ -248,8 +250,34 @@ static qboolean Shader_EvaluateCondition(char **ptr)
else else
{ {
cv = Cvar_Get(token, "", 0, "Shader Conditions"); cv = Cvar_Get(token, "", 0, "Shader Conditions");
if (cv) token = COM_ParseExt ( ptr, false );
conditiontrue = conditiontrue == !!cv->value; if (*token)
{
float rhs;
char cmp[4];
memcpy(cmp, token, 4);
token = COM_ParseExt ( ptr, false );
rhs = atof(token);
if (!strcmp(cmp, "!="))
conditiontrue = cv->value != rhs;
else if (!strcmp(cmp, "=="))
conditiontrue = cv->value == rhs;
else if (!strcmp(cmp, "<"))
conditiontrue = cv->value < rhs;
else if (!strcmp(cmp, "<="))
conditiontrue = cv->value <= rhs;
else if (!strcmp(cmp, ">"))
conditiontrue = cv->value > rhs;
else if (!strcmp(cmp, ">="))
conditiontrue = cv->value >= rhs;
else
conditiontrue = false;
}
else
{
if (cv)
conditiontrue = conditiontrue == !!cv->value;
}
} }
return conditiontrue; return conditiontrue;
@ -814,6 +842,18 @@ static void Shader_ProgramParam ( shader_t *shader, shaderpass_t *pass, char **p
specialint = atoi(token); specialint = atoi(token);
parmtype = SP_TEXTURE; parmtype = SP_TEXTURE;
} }
else if (!Q_stricmp(token, "consti"))
{
token = Shader_ParseSensString(ptr);
specialint = atoi(token);
parmtype = SP_CONSTI;
}
else if (!Q_stricmp(token, "constf"))
{
token = Shader_ParseSensString(ptr);
specialfloat = atof(token);
parmtype = SP_CONSTF;
}
else if (!Q_stricmp(token, "cvari")) else if (!Q_stricmp(token, "cvari"))
{ {
token = Shader_ParseSensString(ptr); token = Shader_ParseSensString(ptr);
@ -895,8 +935,12 @@ static void Shader_ProgramParam ( shader_t *shader, shaderpass_t *pass, char **p
foundone = false; foundone = false;
break; break;
case SP_TEXTURE: case SP_TEXTURE:
case SP_CONSTI:
shader->progparm[shader->numprogparams].ival = specialint; shader->progparm[shader->numprogparams].ival = specialint;
break; break;
case SP_CONSTF:
shader->progparm[shader->numprogparams].fval = specialfloat;
break;
case SP_CVARF: case SP_CVARF:
case SP_CVARI: case SP_CVARI:
shader->progparm[shader->numprogparams].pval = cv; shader->progparm[shader->numprogparams].pval = cv;
@ -1785,7 +1829,6 @@ void Shader_Shutdown (void)
void Shader_SetBlendmode (shaderpass_t *pass) void Shader_SetBlendmode (shaderpass_t *pass)
{ {
#ifdef GLQUAKE /*FIXME: move to backnd*/
if (pass->texgen == T_GEN_DELUXMAP) if (pass->texgen == T_GEN_DELUXMAP)
{ {
pass->blendmode = GL_DOT3_RGB_ARB; pass->blendmode = GL_DOT3_RGB_ARB;
@ -1824,7 +1867,6 @@ void Shader_SetBlendmode (shaderpass_t *pass)
pass->blendmode = GL_DECAL; pass->blendmode = GL_DECAL;
else else
pass->blendmode = GL_MODULATE; pass->blendmode = GL_MODULATE;
#endif
} }
void Shader_Readpass (shader_t *shader, char **ptr) void Shader_Readpass (shader_t *shader, char **ptr)
@ -1971,7 +2013,11 @@ static qboolean Shader_Parsetok (shader_t *shader, shaderpass_t *pass, shaderkey
void Shader_SetPassFlush (shaderpass_t *pass, shaderpass_t *pass2) void Shader_SetPassFlush (shaderpass_t *pass, shaderpass_t *pass2)
{ {
#ifdef GLQUAKE qboolean config_tex_env_combine = 1;//0;
qboolean config_nv_tex_env_combine4 = 1;//0;
qboolean config_multitexure = be_maxpasses > 1;//0;
qboolean config_env_add = 1;//0;
if (((pass->flags & SHADER_PASS_DETAIL) && !r_detailtextures.value) || if (((pass->flags & SHADER_PASS_DETAIL) && !r_detailtextures.value) ||
((pass2->flags & SHADER_PASS_DETAIL) && !r_detailtextures.value) || ((pass2->flags & SHADER_PASS_DETAIL) && !r_detailtextures.value) ||
(pass->flags & SHADER_PASS_VIDEOMAP) || (pass2->flags & SHADER_PASS_VIDEOMAP)) (pass->flags & SHADER_PASS_VIDEOMAP) || (pass2->flags & SHADER_PASS_VIDEOMAP))
@ -1993,19 +2039,19 @@ void Shader_SetPassFlush (shaderpass_t *pass, shaderpass_t *pass2)
{ {
pass->numMergedPasses++; pass->numMergedPasses++;
} }
else if (gl_config.tex_env_combine || gl_config.nv_tex_env_combine4) else if (config_tex_env_combine || config_nv_tex_env_combine4)
{ {
if ( pass->blendmode == GL_REPLACE ) if ( pass->blendmode == GL_REPLACE )
{ {
if ((pass2->blendmode == GL_DECAL && gl_config.tex_env_combine) || if ((pass2->blendmode == GL_DECAL && config_tex_env_combine) ||
(pass2->blendmode == GL_ADD && gl_config.env_add) || (pass2->blendmode == GL_ADD && config_env_add) ||
(pass2->blendmode && pass2->blendmode != GL_ADD) || gl_config.nv_tex_env_combine4) (pass2->blendmode && pass2->blendmode != GL_ADD) || config_nv_tex_env_combine4)
{ {
pass->numMergedPasses++; pass->numMergedPasses++;
} }
} }
else if (pass->blendmode == GL_ADD && else if (pass->blendmode == GL_ADD &&
pass2->blendmode == GL_ADD && gl_config.env_add) pass2->blendmode == GL_ADD && config_env_add)
{ {
pass->numMergedPasses++; pass->numMergedPasses++;
} }
@ -2014,7 +2060,7 @@ void Shader_SetPassFlush (shaderpass_t *pass, shaderpass_t *pass2)
pass->numMergedPasses++; pass->numMergedPasses++;
} }
} }
else if ( qglMTexCoord2fSGIS ) else if (config_multitexure)
{ {
//don't merge more than 2 tmus. //don't merge more than 2 tmus.
if (pass->numMergedPasses != 1) if (pass->numMergedPasses != 1)
@ -2023,7 +2069,7 @@ void Shader_SetPassFlush (shaderpass_t *pass, shaderpass_t *pass2)
// check if we can use R_RenderMeshMultitextured // check if we can use R_RenderMeshMultitextured
if ( pass->blendmode == GL_REPLACE ) if ( pass->blendmode == GL_REPLACE )
{ {
if ( pass2->blendmode == GL_ADD && gl_config.env_add ) if ( pass2->blendmode == GL_ADD && config_env_add )
{ {
pass->numMergedPasses = 2; pass->numMergedPasses = 2;
} }
@ -2036,12 +2082,11 @@ void Shader_SetPassFlush (shaderpass_t *pass, shaderpass_t *pass2)
{ {
pass->numMergedPasses = 2; pass->numMergedPasses = 2;
} }
else if (pass->blendmode == GL_ADD && pass2->blendmode == GL_ADD && gl_config.env_add) else if (pass->blendmode == GL_ADD && pass2->blendmode == GL_ADD && config_env_add)
{ {
pass->numMergedPasses = 2; pass->numMergedPasses = 2;
} }
} }
#endif
} }
void Shader_SetFeatures ( shader_t *s ) void Shader_SetFeatures ( shader_t *s )
@ -2752,13 +2797,24 @@ void Shader_DefaultBSPQ1(char *shortname, shader_t *s, const void *args)
"}\n" "}\n"
"param time time\n" "param time time\n"
"param texture 0 watertexture\n" "param texture 0 watertexture\n"
"param cvarf r_wateralpha wateralpha\n" "if r_wateralpha != 1\n"
"[\n"
"param cvarf r_wateralpha wateralpha\n"
"sort blend\n"
"{\n"
"map $diffuse\n"
"blendfunc gl_src_alpha gl_one_minus_src_alpha\n"
"}\n"
"]\n"
"if r_wateralpha == 1\n"
"[\n"
"param constf 1 wateralpha\n"
"sort opaque\n"
"{\n"
"map $diffuse\n"
"}\n"
"]\n"
"surfaceparm nodlight\n" "surfaceparm nodlight\n"
"{\n"
"map $diffuse\n"
"blendfunc gl_src_alpha gl_one_minus_src_alpha\n"
"}\n"
"sort blend\n"
"}\n" "}\n"
); );
} }

View file

@ -262,6 +262,8 @@ typedef struct {
//things that are set immediatly //things that are set immediatly
SP_FIRSTIMMEDIATE, //never set SP_FIRSTIMMEDIATE, //never set
SP_CONSTI,
SP_CONSTF,
SP_CVARI, SP_CVARI,
SP_CVARF, SP_CVARF,
SP_CVAR3F, SP_CVAR3F,
@ -271,6 +273,7 @@ typedef struct {
union union
{ {
int ival; int ival;
float fval;
void *pval; void *pval;
}; };
} shaderprogparm_t; } shaderprogparm_t;

View file

@ -8,7 +8,11 @@
#define ZEXPORT VARGS #define ZEXPORT VARGS
#include "../libs/zlib.h" #include "../libs/zlib.h"
#ifdef _WIN64
# pragma comment (lib, "../libs/zlib64.lib")
#else
# pragma comment (lib, "../libs/zlib.lib") # pragma comment (lib, "../libs/zlib.lib")
#endif
#else #else
#include <zlib.h> #include <zlib.h>
#endif #endif

View file

@ -1410,7 +1410,7 @@ static int Q3G_SystemCallsVM(void *offset, unsigned int mask, int fn, const int
args[11]=arg[11]; args[11]=arg[11];
args[12]=arg[12]; args[12]=arg[12];
return Q3G_SystemCalls(NULL, ~0, fn, args); return Q3G_SystemCalls(offset, mask, fn, args);
} }
static qintptr_t EXPORT_FN Q3G_SystemCallsNative(qintptr_t arg, ...) static qintptr_t EXPORT_FN Q3G_SystemCallsNative(qintptr_t arg, ...)