One d3d renderer.

Wonder how much this breaks.
Place your bets now.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@2501 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2007-05-25 22:16:29 +00:00
parent b8b56f03cc
commit 1f9484f93d
68 changed files with 14908 additions and 4365 deletions

View file

@ -762,10 +762,20 @@ static long CG_SystemCallsEx(void *offset, unsigned int mask, int fn, const long
break;
case CG_R_REGISTERSHADER:
VM_LONG(ret) = VM_TOHANDLE(R_RegisterPic(VM_POINTER(arg[0])));
if (!*(char*)VM_POINTER(arg[0]))
VM_LONG(ret) = 0;
else if (qrenderer == QR_OPENGL)
VM_LONG(ret) = VM_TOHANDLE(R_RegisterPic(VM_POINTER(arg[0])));
else
VM_LONG(ret) = VM_TOHANDLE(Draw_SafeCachePic(VM_POINTER(arg[0])));
break;
case CG_R_REGISTERSHADERNOMIP:
VM_LONG(ret) = VM_TOHANDLE(R_RegisterPic(VM_POINTER(arg[0])));
if (!*(char*)VM_POINTER(arg[0]))
VM_LONG(ret) = 0;
else if (qrenderer == QR_OPENGL)
VM_LONG(ret) = VM_TOHANDLE(R_RegisterPic(VM_POINTER(arg[0])));
else
VM_LONG(ret) = VM_TOHANDLE(Draw_SafeCachePic(VM_POINTER(arg[0])));
break;
case CG_R_CLEARSCENE: //clear scene
@ -802,16 +812,10 @@ static long CG_SystemCallsEx(void *offset, unsigned int mask, int fn, const long
break;
case CG_R_DRAWSTRETCHPIC:
switch (qrenderer)
{
#ifdef RGLQUAKE
case QR_OPENGL:
GLDraw_ShaderImage(VM_FLOAT(arg[0]), VM_FLOAT(arg[1]), VM_FLOAT(arg[2]), VM_FLOAT(arg[3]), VM_FLOAT(arg[4]), VM_FLOAT(arg[5]), VM_FLOAT(arg[6]), VM_FLOAT(arg[7]), VM_FROMHANDLE(arg[8]));
break;
#endif
default:
break; //FIXME
}
if (qrenderer == QR_OPENGL)
GLDraw_ShaderImage(VM_FLOAT(arg[0]), VM_FLOAT(arg[1]), VM_FLOAT(arg[2]), VM_FLOAT(arg[3]), VM_FLOAT(arg[4]), VM_FLOAT(arg[5]), VM_FLOAT(arg[6]), VM_FLOAT(arg[7]), (void *)VM_LONG(arg[8]));
else
Draw_Image(VM_FLOAT(arg[0]), VM_FLOAT(arg[1]), VM_FLOAT(arg[2]), VM_FLOAT(arg[3]), VM_FLOAT(arg[4]), VM_FLOAT(arg[5]), VM_FLOAT(arg[6]), VM_FLOAT(arg[7]), (mpic_t *)VM_LONG(arg[8]));
break;
case CG_R_LERPTAG: //Lerp tag...
@ -1104,17 +1108,17 @@ void CG_Start (void)
return;
}
#ifdef RGLQUAKE
#if defined(RGLQUAKE) || defined(DIRECT3D)
if (!Draw_SafeCachePic) //no renderer loaded
{
CG_Stop();
return;
}
if (qrenderer != QR_OPENGL)
if (qrenderer != QR_OPENGL && qrenderer != QR_DIRECT3D)
{ //sorry.
CG_Stop();
Host_EndGame("Unable to connect to q3 servers without opengl.\n");
Host_EndGame("Unable to connect to q3 servers without opengl or d3d.\n");
return;
}

View file

@ -266,12 +266,19 @@ qboolean CL_GetDemoMessage (void)
q1usercmd_t q1cmd;
#ifdef NQPROT
if (cls.demoplayback == DPB_NETQUAKE || cls.demoplayback == DPB_QUAKE2)
if (cls.demoplayback == DPB_NETQUAKE
#ifdef Q2CLIENT
|| cls.demoplayback == DPB_QUAKE2
#endif
)
{ //read the nq demo
#ifdef Q2CLIENT
if (cls.demoplayback == DPB_QUAKE2 && (cls.netchan.last_received == realtime || cls.netchan.last_received > realtime-0.1))
return 0;
else if (cls.demoplayback == DPB_NETQUAKE && cls.signon == 4/*SIGNONS*/)
else
#endif
if (cls.demoplayback == DPB_NETQUAKE && cls.signon == 4/*SIGNONS*/)
{
if (!realtime)
{
@ -1717,6 +1724,32 @@ void CL_QTVList_f (void)
qtvrequestsize = 0;
}
void CL_QTVDemos_f (void)
{
char *connrequest;
vfsfile_t *newf;
newf = FS_OpenTCP(Cmd_Argv(1));
if (!newf)
{
Con_Printf("Couldn't connect to proxy\n");
return;
}
connrequest = "QTV\n"
"VERSION: 1\n";
VFS_WRITE(newf, connrequest, strlen(connrequest));
connrequest = "DEMOLIST\n";
VFS_WRITE(newf, connrequest, strlen(connrequest));
connrequest = "\n";
VFS_WRITE(newf, connrequest, strlen(connrequest));
if (qtvrequest)
VFS_CLOSE(qtvrequest);
qtvrequest = newf;
qtvrequestsize = 0;
}
/*
====================
CL_FinishTimeDemo

View file

@ -1453,6 +1453,11 @@ void V_AddLerpEntity(entity_t *in) //a convienience function
ent->angles[0]*=-1;
}
void V_AddLight (vec3_t org, float quant, float r, float g, float b)
{
CL_NewDlightRGB (0, org[0], org[1], org[2], quant, -0.1, r, g, b);
}
/*
===============
CL_LinkPacketEntities

View file

@ -641,7 +641,6 @@ void CL_DrawPrydonCursor(void)
}
}
void ML_UnProject(vec3_t in, vec3_t out, vec3_t viewangles, vec3_t vieworg, float wdivh, float fovy);
void CL_UpdatePrydonCursor(usercmd_t *from, float cursor_screen[2], vec3_t cursor_start, vec3_t cursor_impact, int *entnum)
{
vec3_t cursor_end;
@ -699,7 +698,7 @@ void CL_UpdatePrydonCursor(usercmd_t *from, float cursor_screen[2], vec3_t curso
temp[1] = (-cursor_screen[1]+1)/2;
temp[2] = 1;
ML_UnProject(temp, cursor_end, cl.viewangles[0], vec3_origin, (float)vid.width/vid.height, scr_fov.value );
Matrix4_UnProject(temp, cursor_end, cl.viewangles[0], vec3_origin, (float)vid.width/vid.height, scr_fov.value );
VectorScale(cursor_end, 100000, cursor_end);
VectorAdd(cursor_start, cl.simorg[0], cursor_start);

View file

@ -508,7 +508,7 @@ void CL_SendConnectPacket (
#ifdef HUFFNETWORK
if (compressioncrc && Huff_CompressionCRC(compressioncrc))
{
strcat(data, va("0x%x 0x%x\n", (('H'<<0) + ('U'<<8) + ('F'<<16) + ('F' << 24)), LittleLong(compressioncrc)));
strcat(data, va("0x%x 0x%x\n", PROTOCOL_VERSION_HUFFMAN, LittleLong(compressioncrc)));
cls.netchan.compress = true;
}
else
@ -2846,6 +2846,7 @@ void CL_Init (void)
Cmd_AddCommand ("playdemo", CL_PlayDemo_f);
Cmd_AddCommand ("qtvplay", CL_QTVPlay_f);
Cmd_AddCommand ("qtvlist", CL_QTVList_f);
Cmd_AddCommand ("qtvdemos", CL_QTVDemos_f);
Cmd_AddCommand ("demo_jump", CL_DemoJump_f);
Cmd_AddCommand ("timedemo", CL_TimeDemo_f);

View file

@ -236,7 +236,7 @@ int VARGS Plug_Draw_Character(void *offset, unsigned int mask, const long *arg)
Draw_Character(arg[0], arg[1], (unsigned int)arg[2]);
return 0;
}
void (D3D_Draw_Fill_Colours) (int x, int y, int w, int h);
int VARGS Plug_Draw_Fill(void *offset, unsigned int mask, const long *arg)
{
float x, y, width, height;
@ -260,6 +260,9 @@ int VARGS Plug_Draw_Fill(void *offset, unsigned int mask, const long *arg)
qglEnable(GL_TEXTURE_2D);
return 1;
#endif
case QR_DIRECT3D:
// D3D_Draw_Fill_Colours(x, y, width, height);
break;
default:
break;
}

View file

@ -28,6 +28,75 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
void RSpeedShow(void)
{
int i;
static int samplerspeeds[RSPEED_MAX];
static int samplerquant[RQUANT_MAX];
char *RSpNames[RSPEED_MAX];
char *RQntNames[RQUANT_MAX];
char *s;
static int framecount;
if (!r_speeds.value)
return;
memset(RSpNames, 0, sizeof(RSpNames));
RSpNames[RSPEED_TOTALREFRESH] = "Total refresh";
RSpNames[RSPEED_PROTOCOL] = "Protocol";
RSpNames[RSPEED_LINKENTITIES] = "Entity setup";
RSpNames[RSPEED_WORLDNODE] = "World walking";
RSpNames[RSPEED_WORLD] = "World rendering";
RSpNames[RSPEED_DYNAMIC] = "Lightmap updates";
RSpNames[RSPEED_PARTICLES] = "Particle physics and sorting";
RSpNames[RSPEED_PARTICLESDRAW] = "Particle drawing";
RSpNames[RSPEED_2D] = "2d elements";
RSpNames[RSPEED_SERVER] = "Server";
RSpNames[RSPEED_DRAWENTITIES] = "Entity rendering";
RSpNames[RSPEED_PALETTEFLASHES] = "Palette flashes";
RSpNames[RSPEED_STENCILSHADOWS] = "Stencil Shadows";
RSpNames[RSPEED_FULLBRIGHTS] = "World fullbrights";
RSpNames[RSPEED_FINISH] = "Waiting for card to catch up";
RQntNames[RQUANT_MSECS] = "Microseconds";
RQntNames[RQUANT_EPOLYS] = "Entity Polys";
RQntNames[RQUANT_WPOLYS] = "World Polys";
RQntNames[RQUANT_SHADOWFACES] = "Shadow Faces";
RQntNames[RQUANT_SHADOWEDGES] = "Shadow edges";
RQntNames[RQUANT_LITFACES] = "Lit faces";
for (i = 0; i < RSPEED_MAX; i++)
{
s = va("%i %-30s", samplerspeeds[i], RSpNames[i]);
Draw_String(vid.width-strlen(s)*8, i*8, s);
}
for (i = 0; i < RQUANT_MAX; i++)
{
s = va("%i %-30s", samplerquant[i], RQntNames[i]);
Draw_String(vid.width-strlen(s)*8, (i+RSPEED_MAX)*8, s);
}
s = va("%f %-30s", 100000000.0f/samplerspeeds[RSPEED_TOTALREFRESH], "Framerate");
Draw_String(vid.width-strlen(s)*8, (i+RSPEED_MAX)*8, s);
if (framecount++>=100)
{
for (i = 0; i < RSPEED_MAX; i++)
{
samplerspeeds[i] = rspeeds[i];
rspeeds[i] = 0;
}
for (i = 0; i < RQUANT_MAX; i++)
{
samplerquant[i] = rquant[i];
rquant[i] = 0;
}
framecount=0;
}
}
/*
@ -1050,7 +1119,7 @@ void SCR_CrosshairPosition(int pnum, int *x, int *y)
adj+=v_viewheight.value;
start[2]+=adj;
ML_Project(tr.endpos, end, cl.simangles[pnum], start, (float)rect.width/rect.height, r_refdef.fov_y);
Matrix4_Project(tr.endpos, end, cl.simangles[pnum], start, (float)rect.width/rect.height, r_refdef.fov_y);
*x = rect.x+rect.width*end[0];
*y = rect.y+rect.height*(1-end[1]);
return;
@ -1697,7 +1766,7 @@ int MipColor(int r, int g, int b)
return best;
}
void SCR_ScreenShot (char *filename)
qboolean SCR_ScreenShot (char *filename)
{
int truewidth, trueheight;
qbyte *buffer;
@ -1711,6 +1780,9 @@ void SCR_ScreenShot (char *filename)
buffer = VID_GetRGBInfo(MAX_PREPAD, &truewidth, &trueheight);
if (!buffer)
return false;
#ifdef AVAIL_PNGLIB
if (!strcmp(ext, "png"))
{
@ -1773,6 +1845,8 @@ void SCR_ScreenShot (char *filename)
BZ_Free (buffer);
return true;
}
/*
@ -1828,8 +1902,10 @@ void SCR_ScreenShot_f (void)
}
}
SCR_ScreenShot(pcxname);
Con_Printf ("Wrote %s\n", pcxname);
if (SCR_ScreenShot(pcxname))
Con_Printf ("Wrote %s\n", pcxname);
else
Con_Printf ("Screenshot failed\n");
}

View file

@ -1056,11 +1056,12 @@ long UI_SystemCallsEx(void *offset, unsigned int mask, int fn, const long *arg)
UI_RegisterFont(VM_POINTER(arg[0]), arg[1], VM_POINTER(arg[2]));
break;
case UI_R_REGISTERSHADERNOMIP:
if (!Draw_SafeCachePic || !*(char*)VM_POINTER(arg[0]))
if (!*(char*)VM_POINTER(arg[0]))
VM_LONG(ret) = 0;
else
// VM_LONG(ret) = (long)Draw_SafeCachePic(VM_POINTER(arg[0]));
else if (qrenderer == QR_OPENGL)
VM_LONG(ret) = (long)R_RegisterPic(VM_POINTER(arg[0]));
else
VM_LONG(ret) = (long)Draw_SafeCachePic(VM_POINTER(arg[0]));
break;
case UI_R_CLEARSCENE: //clear scene
@ -1090,9 +1091,10 @@ long UI_SystemCallsEx(void *offset, unsigned int mask, int fn, const long *arg)
// qglDisable(GL_ALPHA_TEST);
// qglEnable(GL_BLEND);
// GL_TexEnv(GL_MODULATE);
if (Draw_Image)
if (qrenderer == QR_OPENGL)
GLDraw_ShaderImage(VM_FLOAT(arg[0]), VM_FLOAT(arg[1]), VM_FLOAT(arg[2]), VM_FLOAT(arg[3]), VM_FLOAT(arg[4]), VM_FLOAT(arg[5]), VM_FLOAT(arg[6]), VM_FLOAT(arg[7]), (void *)VM_LONG(arg[8]));
// Draw_Image(VM_FLOAT(arg[0]), VM_FLOAT(arg[1]), VM_FLOAT(arg[2]), VM_FLOAT(arg[3]), VM_FLOAT(arg[4]), VM_FLOAT(arg[5]), VM_FLOAT(arg[6]), VM_FLOAT(arg[7]), (mpic_t *)VM_LONG(arg[8]));
else
Draw_Image(VM_FLOAT(arg[0]), VM_FLOAT(arg[1]), VM_FLOAT(arg[2]), VM_FLOAT(arg[3]), VM_FLOAT(arg[4]), VM_FLOAT(arg[5]), VM_FLOAT(arg[6]), VM_FLOAT(arg[7]), (mpic_t *)VM_LONG(arg[8]));
break;
case UI_CM_LERPTAG: //Lerp tag...
@ -1753,7 +1755,7 @@ void UI_Start (void)
if (!Draw_SafeCachePic) //no renderer loaded
return;
if (qrenderer != QR_OPENGL)
if (qrenderer != QR_OPENGL && qrenderer != QR_DIRECT3D)
return;
uivm = VM_Create(NULL, "vm/qwui", UI_SystemCalls, UI_SystemCallsEx);

View file

@ -754,6 +754,7 @@ void CL_ReRecord_f (void);
void CL_PlayDemo_f (void);
void CL_QTVPlay_f (void);
void CL_QTVList_f (void);
void CL_QTVDemos_f (void);
void CL_DemoJump_f(void);
void CL_ProgressDemoTime(void);
void CL_TimeDemo_f (void);

View file

@ -1306,10 +1306,6 @@ struct model_s *S_RegisterSexedModel (entity_state_t *ent, char *base)
*/
void V_AddLight (vec3_t org, float quant, float r, float g, float b)
{
CL_NewDlightRGB (0, org[0], org[1], org[2], quant, -0.1, r, g, b);
}
/*
===============
CL_AddPacketEntities

View file

@ -3,6 +3,10 @@
#include "glquake.h"
#endif
#ifdef D3DQUAKE
#include "d3dquake.h"
#endif
cvar_t r_dodgytgafiles = SCVAR("r_dodgytgafiles", "0"); //Certain tgas are upside down.
//This is due to a bug in tenebrae.
//(normally) the textures are actually the right way around.
@ -1727,7 +1731,13 @@ void BoostGamma(qbyte *rgba, int width, int height)
#endif
}
#if defined(RGLQUAKE)
#if defined(RGLQUAKE) || defined(D3DQUAKE)
#ifdef DDS
#ifndef GL_COMPRESSED_RGB_S3TC_DXT1_EXT
@ -1925,16 +1935,16 @@ int Mod_LoadHiResTexture(char *name, char *subpath, qboolean mipmap, qboolean al
*data = '#';
}
if ((len = GL_FindTexture(name))!=-1) //don't bother if it already exists.
if ((len = R_FindTexture(name))!=-1) //don't bother if it already exists.
return len;
if (subpath && *subpath)
{
snprintf(fname, sizeof(fname)-1, "%s/%s", subpath, name);
if ((len = GL_FindTexture(fname))!=-1) //don't bother if it already exists.
if ((len = R_FindTexture(fname))!=-1) //don't bother if it already exists.
return len;
}
if ((len = GL_LoadCompressed(name)))
if ((len = R_LoadCompressed(name)))
return len;
if (strchr(name, '/')) //never look in a root dir for the pic
@ -1985,10 +1995,10 @@ int Mod_LoadHiResTexture(char *name, char *subpath, qboolean mipmap, qboolean al
if (i == 1)
{ //if it came from a special subpath (eg: map specific), upload it using the subpath prefix
snprintf(fname, sizeof(fname)-1, "%s/%s", subpath, name);
len = GL_LoadTexture32 (fname, image_width, image_height, (unsigned*)data, mipmap, alpha);
len = R_LoadTexture32 (fname, image_width, image_height, (unsigned*)data, mipmap, alpha);
}
else
len = GL_LoadTexture32 (name, image_width, image_height, (unsigned*)data, mipmap, alpha);
len = R_LoadTexture32 (name, image_width, image_height, (unsigned*)data, mipmap, alpha);
BZ_Free(data);
@ -2008,7 +2018,7 @@ int Mod_LoadHiResTexture(char *name, char *subpath, qboolean mipmap, qboolean al
//now look in wad files. (halflife compatability)
data = W_GetTexture(name, &image_width, &image_height, &alphaed);
if (data)
return GL_LoadTexture32 (name, image_width, image_height, (unsigned*)data, mipmap, alphaed);
return R_LoadTexture32 (name, image_width, image_height, (unsigned*)data, mipmap, alphaed);
return 0;
}
int Mod_LoadReplacementTexture(char *name, char *subpath, qboolean mipmap, qboolean alpha, qboolean gammaadjust)
@ -2044,10 +2054,10 @@ int Mod_LoadBumpmapTexture(char *name, char *subpath)
COM_StripExtension(name, nicename, sizeof(nicename));
if ((len = GL_FindTexture(name))!=-1) //don't bother if it already exists.
if ((len = R_FindTexture(name))!=-1) //don't bother if it already exists.
return len;
if ((len = GL_LoadCompressed(name)))
if ((len = R_LoadCompressed(name)))
return len;
if (strchr(name, '/')) //never look in a root dir for the pic
@ -2081,7 +2091,7 @@ int Mod_LoadBumpmapTexture(char *name, char *subpath)
if ((data = ReadTargaFile(buf, com_filesize, &image_width, &image_height, 2))) //Only load a greyscale image.
{
TRACE(("dbg: Mod_LoadBumpmapTexture: tga %s loaded\n", name));
len = GL_LoadTexture8Bump(name, image_width, image_height, data, true, r_shadow_bumpscale_bumpmap.value);
len = R_LoadTexture8Bump(name, image_width, image_height, data, true, r_shadow_bumpscale_bumpmap.value);
BZ_Free(data);
}
else

View file

@ -1208,7 +1208,7 @@ void IN_ReInit (void)
{
IN_StartupMouse ();
IN_StartupJoystick ();
IN_ActivateMouse();
// IN_ActivateMouse();
}
void IN_Init (void)

View file

@ -736,7 +736,8 @@ menucheck_t *MC_AddCheckBoxFunc(menu_t *menu, int x, int y, const char *text, qb
return n;
}
menuslider_t *MC_AddSlider(menu_t *menu, int x, int y, const char *text, cvar_t *var, float min, float max)
//delta may be 0
menuslider_t *MC_AddSlider(menu_t *menu, int x, int y, const char *text, cvar_t *var, float min, float max, float delta)
{
menuslider_t *n = Z_Malloc(sizeof(menuslider_t)+strlen(text)+1);
n->common.type = mt_slider;
@ -759,6 +760,8 @@ menuslider_t *MC_AddSlider(menu_t *menu, int x, int y, const char *text, cvar_t
n->min = min;
n->max = max;
n->smallchange = delta;
n->largechange = delta*5;
n->common.next = menu->options;
menu->options = (menuoption_t *)n;
@ -999,35 +1002,41 @@ menubutton_t *VARGS MC_AddConsoleCommandf(menu_t *menu, int x, int y, const char
void MC_Slider_Key(menuslider_t *option, int key)
{
float range = (option->current - option->min)/(option->max-option->min);
float range = option->current;
float delta;
if (option->smallchange)
delta = option->smallchange;
else
delta = 0.1;
if (key == K_LEFTARROW || key == K_MWHEELDOWN)
{
range -= 0.1;
if (range < 0)
range = 0;
option->current = range = (range * (option->max-option->min)) + option->min;
range -= delta;
if (range < option->min)
range = option->min;
option->current = range;
if (option->var)
Cvar_SetValue(option->var, range);
}
else if (key == K_RIGHTARROW || key == K_MWHEELUP)
{
range += 0.1;
if (range > 1)
range = 1;
option->current = range = (range * (option->max-option->min)) + option->min;
range += delta;
if (range > option->max)
range = option->max;
option->current = range;
if (option->var)
Cvar_SetValue(option->var, range);
}
else if (key == K_ENTER || key == K_MOUSE1)
{
range += 0.1;
range += delta;
if (range >= 1.05)
range = 0;
if (range > 1)
range = 1;
option->current = range = (range * (option->max-option->min)) + option->min;
if (range >= option->max + delta/2)
range = option->min;
if (range > option->max)
range = option->max;
option->current = range;
if (option->var)
Cvar_SetValue(option->var, range);
}

View file

@ -39,6 +39,18 @@ void M_Menu_MultiPlayer_f (void)
}
else if (mgt == MGT_HEXEN2)
{
MC_AddCenterPicture(menu, 0, "gfx/menu/title4.lmp");
mgt=64;
menu->selecteditem = (menuoption_t*)
MC_AddConsoleCommandHexen2BigFont (menu, 80, mgt, "Join A Game ", "menu_slist\n");mgt+=20;
MC_AddConsoleCommandHexen2BigFont (menu, 80, mgt, "Old Browser ", "menu_serversold\n");mgt+=20;
MC_AddConsoleCommandHexen2BigFont (menu, 80, mgt, "New Server ", "menu_newmulti\n");mgt+=20;
MC_AddConsoleCommandHexen2BigFont (menu, 80, mgt, "Player Setup", "menu_setup\n");mgt+=20;
MC_AddConsoleCommandHexen2BigFont (menu, 80, mgt, "Demos ", "menu_demo\n");mgt+=20;
menu->cursoritem = (menuoption_t *)MC_AddCursor(menu, 48, 64);
return;
}
else if (QBigFontWorks())
{
@ -435,7 +447,7 @@ void M_Menu_GameOptions_f (void)
info->timelimit = MC_AddCombo (menu, 64, y, " Time Limit", (const char **)timelimitoptions, timelimit.value/5);y+=8;
info->fraglimit = MC_AddCombo (menu, 64, y, " Frag Limit", (const char **)fraglimitoptions, fraglimit.value/10);y+=8;
y+=8;
MC_AddSlider (menu, 64-7*8, y, "Extra edict support", &pr_maxedicts, 512, 2047);y+=8;
MC_AddSlider (menu, 64-7*8, y, "Extra edict support", &pr_maxedicts, 512, 2047, 256);y+=8;
y+=8;
if (mgt == MGT_QUAKE2)
info->mapnameedit = MC_AddEdit (menu, 64, y, " map", "base1");

View file

@ -37,7 +37,7 @@ void M_Menu_Options_f (void)
{
int mgt;
extern cvar_t cl_standardchat;
extern cvar_t cl_standardmsg;
extern cvar_t cl_standardmsg, crosshair;
#ifdef _WIN32
extern qboolean vid_isfullscreen;
#endif
@ -72,7 +72,8 @@ void M_Menu_Options_f (void)
MC_AddConsoleCommand(menu, 16, y, " Go to console", "toggleconsole\nplay misc/menu2.wav\n"); y+=8;
MC_AddConsoleCommand(menu, 16, y, " Reset to defaults", "exec default.cfg\nplay misc/menu2.wav\n"); y+=8;
MC_AddSlider(menu, 16, y, " Mouse Speed", &sensitivity, 1, 10); y+=8;
MC_AddSlider(menu, 16, y, " Mouse Speed", &sensitivity, 1, 10, 0.5); y+=8;
MC_AddSlider(menu, 16, y, " Crosshair", &crosshair, 0, 22, 1); y+=8;
MC_AddCheckBox(menu, 16, y, " Always Run", NULL,0)->func = M_Options_AlwaysRun; y+=8;
MC_AddCheckBox(menu, 16, y, " Invert Mouse", NULL,0)->func = M_Options_InvertMouse; y+=8;
@ -282,9 +283,9 @@ void M_Menu_Audio_f (void)
menu->selecteditem = (union menuoption_s *)
MC_AddSlider(menu, 16, y, " CD Music Volume", &bgmvolume, 0, 1);y+=8;
MC_AddSlider(menu, 16, y, " Sound Volume", &volume, 0, 1);y+=8;
MC_AddSlider(menu, 16, y, " Ambient Volume", &ambient_level, 0, 1);y+=8;
MC_AddSlider(menu, 16, y, " CD Music Volume", &bgmvolume, 0, 1, 0.1);y+=8;
MC_AddSlider(menu, 16, y, " Sound Volume", &volume, 0, 1, 0.1);y+=8;
MC_AddSlider(menu, 16, y, " Ambient Volume", &ambient_level, 0, 1, 0.1);y+=8;
MC_AddCheckBox(menu, 16, y, " no sound", &nosound,0);y+=8;
MC_AddCheckBox(menu, 16, y, " precache", &precache,0);y+=8;
MC_AddCheckBox(menu, 16, y, " Low Quality Sound", &loadas8bit,0);y+=8;
@ -482,7 +483,7 @@ void M_Menu_FPS_f (void)
MC_AddCheckBox(menu, 48, y, " Dynamic shadows", &r_shadows,0);y+=8;
MC_AddCheckBox(menu, 48, y, " Realtime Lights", &r_shadow_realtime_world,0);y+=8;
MC_AddCheckBox(menu, 48, y, " Waterwarp", &r_waterwarp,0);y+=8;
MC_AddSlider(menu, 48, y, " Motion blur", &gl_motionblur, 0, 0.99);y+=8;
MC_AddSlider(menu, 48, y, " Motion blur", &gl_motionblur, 0, 0.99, 0);y+=8;
break;
#endif
#ifdef SWQUAKE
@ -490,8 +491,8 @@ void M_Menu_FPS_f (void)
if (r_pixbytes == 4)
{MC_AddCheckBox(menu, 48, y, " Load .lit files", &r_loadlits,0);y+=8;}
MC_AddCheckBox(menu, 48, y, " Texture Smoothing", &d_smooth,0);y+=8;
MC_AddSlider(menu, 48, y, " Mipmap scale", &d_mipscale, 0.1, 3);y+=8;
MC_AddSlider(menu, 48, y, " Mipmap Capping", &d_mipcap, 0, 3);y+=8;
MC_AddSlider(menu, 48, y, " Mipmap scale", &d_mipscale, 0.1, 3, 1);y+=8;
MC_AddSlider(menu, 48, y, " Mipmap Capping", &d_mipcap, 0, 3, 1);y+=8;
break;
#endif
default:

View file

@ -137,7 +137,7 @@ void M_MenuS_Slider_f (void)
cvar = Cvar_Get(cvarname, text, 0, "User variables");
if (!cvar)
return;
MC_AddSlider(menu_script, x, y, text, cvar, min, max);
MC_AddSlider(menu_script, x, y, text, cvar, min, max, 0);
}
void M_MenuS_Picture_f (void)

View file

@ -338,6 +338,55 @@ bindnames_t q2bindnames[] =
};
#endif
bindnames_t h2bindnames[] =
{
{"+attack", "attack "},
{"impulse 10", "change weapon "},
{"+jump", "jump / swim up"},
{"+forward", "walk forward "},
{"+back", "backpedal "},
{"+left", "turn left "},
{"+right", "turn right "},
{"+speed", "run "},
{"+moveleft", "step left "},
{"+moveright", "step right "},
{"+strafe", "sidestep "},
{"+crouch", "crouch "},
{"+lookup", "look up "},
{"+lookdown", "look down "},
{"centerview", "center view "},
{"+mlook", "mouse look "},
{"+klook", "keyboard look "},
{"+moveup", "swim up "},
{"+movedown", "swim down "},
{"impulse 13", "lift object "},
{"invuse", "use inv item "},
{"impulse 44", "drop inv item "},
{"+showinfo", "full inventory"},
{"+showdm", "info / frags "},
//{"toggle_dm", "toggle frags "},
//{"+infoplaque", "objectives "}, //requires pulling info out of the mod... on the client.
{"invleft", "inv move left "},
{"invright", "inv move right"},
{"impulse 100", "inv:torch "},
{"impulse 101", "inv:qrtz flask"},
{"impulse 102", "inv:mystic urn"},
{"impulse 103", "inv:krater "},
{"impulse 104", "inv:chaos devc"},
{"impulse 105", "inv:tome power"},
{"impulse 106", "inv:summon stn"},
{"impulse 107", "inv:invisiblty"},
{"impulse 108", "inv:glyph "},
{"impulse 109", "inv:boots "},
{"impulse 110", "inv:repulsion "},
{"impulse 111", "inv:bo peep "},
{"impulse 112", "inv:flight "},
{"impulse 113", "inv:force cube"},
{"impulse 114", "inv:icon defn "},
{NULL}
};
bindnames_t *bindnames;
int numbindnames;
@ -348,6 +397,7 @@ void M_Menu_Keys_f (void)
{
int y;
menu_t *menu;
int mgt;
key_dest = key_menu;
m_state = m_complex;
@ -356,11 +406,15 @@ void M_Menu_Keys_f (void)
MC_AddCenterPicture(menu, 4, "gfx/ttl_cstm.lmp");
mgt = M_GameType();
#ifdef Q2CLIENT
if (cls.protocol == CP_QUAKE2)
if (mgt == MGT_QUAKE2) //quake2 main menu.
bindnames = q2bindnames;
else
#endif
if (mgt == MGT_HEXEN2)
bindnames = h2bindnames;
else
bindnames = qwbindnames;
y = 48;

View file

@ -279,7 +279,7 @@ menupicture_t *MC_AddSelectablePicture(menu_t *menu, int x, int y, char *picname
menupicture_t *MC_AddStrechPicture(menu_t *menu, int x, int y, int width, int height, char *picname);
menupicture_t *MC_AddCenterPicture(menu_t *menu, int y, char *picname);
menupicture_t *MC_AddCursor(menu_t *menu, int x, int y);
menuslider_t *MC_AddSlider(menu_t *menu, int x, int y, const char *text, cvar_t *var, float min, float max);
menuslider_t *MC_AddSlider(menu_t *menu, int x, int y, const char *text, cvar_t *var, float min, float max, float delta);
menucheck_t *MC_AddCheckBox(menu_t *menu, int x, int y, const char *text, cvar_t *var, int cvarbitmask);
menucheck_t *MC_AddCheckBoxFunc(menu_t *menu, int x, int y, const char *text, qboolean (*func) (menucheck_t *option, menu_t *menu, chk_set_t set), int bits);
menubutton_t *MC_AddConsoleCommand(menu_t *menu, int x, int y, const char *text, const char *command);

View file

@ -100,8 +100,8 @@ extern void FNC(Mod_TouchModel) (char *name);
extern void FNC(Mod_NowLoadExternal) (void);
extern void FNC(Mod_Think) (void);
extern qboolean FNC(Mod_GetTag) (struct model_s *model, int tagnum, int frame, int frame2, float f2ness, float f1time, float f2time, float *transforms);
extern int FNC(Mod_TagNumForName) (struct model_s *model, char *name);
//extern qboolean FNC(Mod_GetTag) (struct model_s *model, int tagnum, int frame, int frame2, float f2ness, float f1time, float f2time, float *transforms);
//extern int FNC(Mod_TagNumForName) (struct model_s *model, char *name);
extern int FNC(Mod_SkinForName) (struct model_s *model, char *name);
#undef FNC

View file

@ -856,10 +856,10 @@ static void buildmatricies(void)
float modelview[16];
float proj[16];
ML_ModelViewMatrix(modelview, r_refdef.viewangles, r_refdef.vieworg);
ML_ProjectionMatrix2(proj, r_refdef.fov_x, r_refdef.fov_y);
Matrix4_ModelViewMatrix(modelview, r_refdef.viewangles, r_refdef.vieworg);
Matrix4_Projection2(proj, r_refdef.fov_x, r_refdef.fov_y, 4);
Matrix4_Multiply(proj, modelview, mvp);
Matrix4x4_Invert_Simple((matrix4x4_t*)mvpi, (matrix4x4_t*)mvp); //not actually used in this function.
Matrix4_Invert_Simple((matrix4x4_t*)mvpi, (matrix4x4_t*)mvp); //not actually used in this function.
csqc_rebuildmatricies = false;
}

View file

@ -32,6 +32,9 @@ The engine has a few builtins.
#ifdef RGLQUAKE
#include "glquake.h"//hack
#endif
#ifdef D3DQUAKE
#include "d3dquake.h"//hack
#endif
#include "renderque.h"
@ -143,24 +146,6 @@ cvar_t r_part_contentswitch = SCVAR("r_part_contentswitch", "1");
static float particletime;
typedef struct skytris_s {
struct skytris_s *next;
vec3_t org;
vec3_t x;
vec3_t y;
float area;
float nexttime;
msurface_t *face;
} skytris_t;
//these could be deltas or absolutes depending on ramping mode.
typedef struct {
vec3_t rgb;
float alpha;
float scale;
float rotation;
} ramp_t;
#define APPLYBLEND(bm) \
switch (bm) \
{ \
@ -179,102 +164,29 @@ typedef struct {
break; \
}
// TODO: merge in alpha with rgb to gain benefit of vector opts
typedef struct part_type_s {
char name[MAX_QPATH];
char texname[MAX_QPATH];
vec3_t rgb;
vec3_t rgbchange;
vec3_t rgbrand;
int colorindex;
int colorrand;
float rgbchangetime;
vec3_t rgbrandsync;
float scale, alpha;
float alphachange;
float die, randdie;
float randomvel, veladd;
float orgadd;
float offsetspread;
float offsetspreadvert;
float randomvelvert;
float randscale;
#define APPLYD3DBLEND(bm) \
switch (bm) \
{ \
case BM_ADD: \
pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA); \
pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE); \
break; \
case BM_SUBTRACT: \
pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA); \
pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCCOLOR); \
break; \
case BM_BLENDCOLOUR: \
pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCCOLOR); \
pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCCOLOR); \
break; \
case BM_BLEND: \
default: \
pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA); \
pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA); \
break; \
}
float spawntime;
float spawnchance;
enum {PT_NORMAL, PT_SPARK, PT_SPARKFAN, PT_TEXTUREDSPARK, PT_BEAM, PT_DECAL} type;
blendmode_t blendmode;
float rotationstartmin, rotationstartrand;
float rotationmin, rotationrand;
float scaledelta;
float count;
float countrand;
int texturenum;
int assoc;
int cliptype;
int inwater;
float clipcount;
int emit;
float emittime;
float emitrand;
float emitstart;
float areaspread;
float areaspreadvert;
float scalefactor;
float invscalefactor;
float spawnparam1;
float spawnparam2;
/* float spawnparam3; */
float offsetup; // make this into a vec3_t later with dir, possibly for mdls
enum {
SM_BOX, //box = even spread within the area
SM_CIRCLE, //circle = around edge of a circle
SM_BALL, //ball = filled sphere
SM_SPIRAL, //spiral = spiral trail
SM_TRACER, //tracer = tracer trail
SM_TELEBOX, //telebox = q1-style telebox
SM_LAVASPLASH, //lavasplash = q1-style lavasplash
SM_UNICIRCLE, //unicircle = uniform circle
SM_FIELD, //field = synced field (brightfield, etc)
SM_DISTBALL // uneven distributed ball
} spawnmode;
float gravity;
vec3_t friction;
float clipbounce;
int stains;
enum {RAMP_NONE, RAMP_DELTA, RAMP_ABSOLUTE} rampmode;
int rampindexes;
ramp_t *ramp;
int loaded;
particle_t *particles;
clippeddecal_t *clippeddecals;
beamseg_t *beams;
skytris_t *skytris;
struct part_type_s *nexttorun;
unsigned int flags;
#define PT_VELOCITY 0x001
#define PT_FRICTION 0x002
#define PT_CHANGESCOLOUR 0x004
#define PT_CITRACER 0x008 // Q1-style tracer behavior for colorindex
#define PT_INVFRAMETIME 0x010 // apply inverse frametime to count (causes emits to be per frame)
#define PT_AVERAGETRAIL 0x020 // average trail points from start to end, useful with t_lightning, etc
#define PT_NOSTATE 0x040 // don't use trailstate for this emitter (careful with assoc...)
#define PT_NOSPREADFIRST 0x080 // don't randomize org/vel for first generated particle
#define PT_NOSPREADLAST 0x100 // don't randomize org/vel for last generated particle
unsigned int state;
#define PS_INRUNLIST 0x1 // particle type is currently in execution list
} part_type_t;
int numparticletypes;
part_type_t *part_type;
part_type_t *part_run_list;
@ -403,28 +315,56 @@ static int CheckAssosiation(char *name, int from)
return orig;
}
#ifdef RGLQUAKE
void P_LoadTexture(part_type_t *ptype, qboolean warn)
{
if (*ptype->texname && strcmp(ptype->texname, "default"))
switch (qrenderer)
{
ptype->texturenum = Mod_LoadHiResTexture(ptype->texname, "particles", true, true, true);
if (!ptype->texturenum)
#ifdef RGLQUAKE
case QR_OPENGL:
if (*ptype->texname && strcmp(ptype->texname, "default"))
{
if (warn)
Con_DPrintf("Couldn't load texture %s for particle effect %s\n", ptype->texname, ptype->name);
ptype->texturenum = Mod_LoadHiResTexture(ptype->texname, "particles", true, true, true);
if (strstr(ptype->texname, "glow") || strstr(ptype->texname, "ball"))
ptype->texturenum = balltexture;
else
ptype->texturenum = explosiontexture;
if (!ptype->texturenum)
{
if (warn)
Con_DPrintf("Couldn't load texture %s for particle effect %s\n", ptype->texname, ptype->name);
if (strstr(ptype->texname, "glow") || strstr(ptype->texname, "ball"))
ptype->texturenum = balltexture;
else
ptype->texturenum = explosiontexture;
}
}
}
else
ptype->texturenum = explosiontexture;
}
else
ptype->texturenum = explosiontexture;
break;
#endif
#ifdef D3DQUAKE
case QR_DIRECT3D:
if (*ptype->texname && strcmp(ptype->texname, "default"))
{
ptype->d3dtexture = NULL;//Mod_LoadHiResTexture(ptype->texname, "particles", true, true, true);
if (!ptype->d3dtexture)
{
if (warn)
Con_DPrintf("Couldn't load texture %s for particle effect %s\n", ptype->texname, ptype->name);
if (strstr(ptype->texname, "glow") || strstr(ptype->texname, "ball"))
ptype->d3dtexture = d3dballtexture;
else
ptype->d3dtexture = d3dexplosiontexture;
}
}
else
ptype->d3dtexture = d3dexplosiontexture;
break;
#endif
default:
break;
}
}
//Uses FTE's multiline console stuff.
//This is the function that loads the effect descriptions (via console).
@ -1030,12 +970,7 @@ void P_ParticleEffect_f(void)
Con_Printf("Particle type %s has a ramp but no ramp mode\n", ptype->name);
}
#ifdef RGLQUAKE
if (qrenderer == QR_OPENGL)
{
P_LoadTexture(ptype, true);
}
#endif
P_LoadTexture(ptype, true);
}
//assosiate a point effect with a model.
@ -1061,6 +996,8 @@ void P_AssosiateEffect_f (void)
}
model = Mod_FindName(modelname);
if (!model)
return;
if (!cls.demoplayback && (model->flags & EF_ROTATE))
{
Con_Printf("Sorry: You may not assosiate effects with item model \"%s\"\n", modelname);
@ -1094,6 +1031,8 @@ void P_AssosiateTrail_f (void)
}
model = Mod_FindName(modelname);
if (!model)
return;
effectnum = P_AllocateParticleType(effectname);
model->particletrail = effectnum;
model->engineflags |= MDLF_NODEFAULTTRAIL; //we could have assigned the trail to a model that wasn't loaded.
@ -1508,15 +1447,10 @@ void P_ClearParticles (void)
particletime = cl.time;
#ifdef RGLQUAKE
if (qrenderer == QR_OPENGL)
for (i = 0; i < numparticletypes; i++)
{
for (i = 0; i < numparticletypes; i++)
{
P_LoadTexture(&part_type[i], false);
}
P_LoadTexture(&part_type[i], false);
}
#endif
for (i = 0; i < numparticletypes; i++)
{
@ -3942,6 +3876,422 @@ void SWD_DrawParticleBeam(beamseg_t *beam, part_type_t *type)
D_DrawSparkTrans(p, p->org, q->org, type->blendmode);
}
#endif
#ifdef D3DQUAKE
typedef struct d3dparticlevert_s {
float org[3];
unsigned int colour;
float s, t; //these could actually be preinitialised
} d3dparticlevert_t;
d3dparticlevert_t d3dparticlevert[4];
typedef struct d3dparticlevertut_s {
float org[3];
unsigned int colour;
} d3dparticlevertut_t;
d3dparticlevertut_t d3dparticlevertut[4];
unsigned short d3dparticlevertindexes[] =
{
0, 1, 2,
0, 2, 3
};
void D3D_DrawParticleBlob(particle_t *p, part_type_t *type)
{
float scale;
float x;
float y;
unsigned int colour;
int cb, cg, cr, ca;
if (lastgltype != type)
{
lastgltype = type;
pD3DDev->lpVtbl->SetTexture(pD3DDev, 0, type->d3dtexture);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
APPLYD3DBLEND(type->blendmode);
}
scale = (p->org[0] - r_origin[0])*vpn[0] + (p->org[1] - r_origin[1])*vpn[1]
+ (p->org[2] - r_origin[2])*vpn[2];
scale = (scale*p->scale)*(type->invscalefactor) + p->scale * (type->scalefactor*250);
if (scale < 20)
scale = 0.25;
else
scale = 0.25 + scale * 0.001;
cr = p->rgb[0]*255;
if (cr < 0) cr = 0;
if (cr > 255) cr = 255;
cg = p->rgb[1]*255;
if (cg < 0) cg = 0;
if (cg > 255) cg = 255;
cb = p->rgb[2]*255;
if (cb < 0) cb = 0;
if (cb > 255) cb = 255;
ca = p->alpha*255;
if (ca < 0) ca = 0;
if (ca > 255) ca = 255;
colour = (cb) | (cg<<8) | (cr << 16) | (ca << 24);
if (p->angle)
{
x = sin(p->angle)*scale;
y = cos(p->angle)*scale;
}
else
{
x = 0;
y = scale;
}
d3dparticlevert[0].s = 0;
d3dparticlevert[0].t = 0;
d3dparticlevert[0].colour = colour;
d3dparticlevert[0].org[0] = p->org[0] - x*pright[0] - y*pup[0];
d3dparticlevert[0].org[1] = p->org[1] - x*pright[1] - y*pup[1];
d3dparticlevert[0].org[2] = p->org[2] - x*pright[2] - y*pup[2];
d3dparticlevert[1].s = 0;
d3dparticlevert[1].t = 1;
d3dparticlevert[1].colour = colour;
d3dparticlevert[1].org[0] = p->org[0] - y*pright[0] + x*pup[0];
d3dparticlevert[1].org[1] = p->org[1] - y*pright[1] + x*pup[1];
d3dparticlevert[1].org[2] = p->org[2] - y*pright[2] + x*pup[2];
d3dparticlevert[2].s = 1;
d3dparticlevert[2].t = 1;
d3dparticlevert[2].colour = colour;
d3dparticlevert[2].org[0] = p->org[0] + x*pright[0] + y*pup[0];
d3dparticlevert[2].org[1] = p->org[1] + x*pright[1] + y*pup[1];
d3dparticlevert[2].org[2] = p->org[2] + x*pright[2] + y*pup[2];
d3dparticlevert[3].s = 1;
d3dparticlevert[3].t = 0;
d3dparticlevert[3].colour = colour;
d3dparticlevert[3].org[0] = p->org[0] + y*pright[0] - x*pup[0];
d3dparticlevert[3].org[1] = p->org[1] + y*pright[1] - x*pup[1];
d3dparticlevert[3].org[2] = p->org[2] + y*pright[2] - x*pup[2];
pD3DDev->lpVtbl->DrawIndexedPrimitive(pD3DDev, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1, d3dparticlevert, 4, d3dparticlevertindexes, 6, 0);
}
void D3D_DrawParticleSpark(particle_t *p, part_type_t *type)
{
vec3_t v, crv, o2;
unsigned int colour;
int cb, cg, cr, ca;
if (lastgltype != type)
{
lastgltype = type;
pD3DDev->lpVtbl->SetTexture(pD3DDev, 0, type->d3dtexture);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
APPLYD3DBLEND(type->blendmode);
}
cr = p->rgb[0]*255;
if (cr < 0) cr = 0;
if (cr > 255) cr = 255;
cg = p->rgb[1]*255;
if (cg < 0) cg = 0;
if (cg > 255) cg = 255;
cb = p->rgb[2]*255;
if (cb < 0) cb = 0;
if (cb > 255) cb = 255;
ca = p->alpha*255;
if (ca < 0) ca = 0;
if (ca > 255) ca = 255;
colour = (cb) | (cg<<8) | (cr << 16) | (ca << 24);
VectorSubtract(r_refdef.vieworg, p->org, v);
CrossProduct(v, p->vel, crv);
VectorNormalize(crv);
VectorMA(p->org, -p->scale/2, crv, d3dparticlevert[0].org);
d3dparticlevert[0].s = 0;
d3dparticlevert[0].t = 0;
d3dparticlevert[0].colour = colour;
VectorMA(p->org, p->scale/2, crv, d3dparticlevert[1].org);
d3dparticlevert[1].s = 0;
d3dparticlevert[1].t = 1;
d3dparticlevert[1].colour = colour;
VectorMA(p->org, 0.1, p->vel, o2);
VectorSubtract(r_refdef.vieworg, o2, v);
CrossProduct(v, p->vel, crv);
VectorNormalize(crv);
VectorMA(o2, p->scale/2, crv, d3dparticlevert[2].org);
d3dparticlevert[2].s = 1;
d3dparticlevert[2].t = 1;
d3dparticlevert[2].colour = colour;
VectorMA(o2, -p->scale/2, crv, d3dparticlevert[3].org);
d3dparticlevert[3].s = 1;
d3dparticlevert[3].t = 0;
d3dparticlevert[3].colour = colour;
pD3DDev->lpVtbl->DrawIndexedPrimitive(pD3DDev, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1, d3dparticlevert, 4, d3dparticlevertindexes, 6, 0);
}
void D3D_DrawParticleBeam(beamseg_t *b, part_type_t *type)
{
vec3_t v;
vec3_t crv;
beamseg_t *c;
particle_t *p;
particle_t *q;
float ts;
unsigned int colour;
int cb, cg, cr, ca;
if (lastgltype != type)
{
lastgltype = type;
pD3DDev->lpVtbl->SetTexture(pD3DDev, 0, type->d3dtexture);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
APPLYD3DBLEND(type->blendmode);
}
c = b->next;
q = c->p;
p = b->p;
cr = q->rgb[0]*255;
if (cr < 0) cr = 0;
if (cr > 255) cr = 255;
cg = q->rgb[1]*255;
if (cg < 0) cg = 0;
if (cg > 255) cg = 255;
cb = q->rgb[2]*255;
if (cb < 0) cb = 0;
if (cb > 255) cb = 255;
ca = q->alpha*255;
if (ca < 0) ca = 0;
if (ca > 255) ca = 255;
colour = (cb) | (cg<<8) | (cr << 16) | (ca << 24);
c = b->next;
q = c->p;
p = b->p;
VectorSubtract(r_refdef.vieworg, q->org, v);
VectorNormalize(v);
CrossProduct(c->dir, v, crv);
ts = c->texture_s*type->rotationstartmin + particletime*type->rotationmin;
VectorMA(q->org, -q->scale, crv, d3dparticlevert[0].org);
d3dparticlevert[0].s = ts;
d3dparticlevert[0].t = 0;
d3dparticlevert[0].colour = colour;
VectorMA(q->org, q->scale, crv, d3dparticlevert[1].org);
d3dparticlevert[1].s = ts;
d3dparticlevert[1].t = 1;
d3dparticlevert[1].colour = colour;
cr = p->rgb[0]*255;
if (cr < 0) cr = 0;
if (cr > 255) cr = 255;
cg = p->rgb[1]*255;
if (cg < 0) cg = 0;
if (cg > 255) cg = 255;
cb = p->rgb[2]*255;
if (cb < 0) cb = 0;
if (cb > 255) cb = 255;
ca = p->alpha*255;
if (ca < 0) ca = 0;
if (ca > 255) ca = 255;
colour = (cb) | (cg<<8) | (cr << 16) | (ca << 24);
VectorSubtract(r_refdef.vieworg, p->org, v);
VectorNormalize(v);
CrossProduct(b->dir, v, crv); // replace with old p->dir?
ts = b->texture_s*type->rotationstartmin + particletime*type->rotationmin;
VectorMA(p->org, p->scale, crv, d3dparticlevert[2].org);
d3dparticlevert[2].s = ts;
d3dparticlevert[2].t = 1;
d3dparticlevert[2].colour = colour;
VectorMA(p->org, -p->scale, crv, d3dparticlevert[3].org);
d3dparticlevert[3].s = ts;
d3dparticlevert[3].t = 0;
d3dparticlevert[3].colour = colour;
pD3DDev->lpVtbl->DrawIndexedPrimitive(pD3DDev, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1, d3dparticlevert, 4, d3dparticlevertindexes, 6, 0);
}
void D3D_DrawParticleBeamUT(beamseg_t *b, part_type_t *type)
{
vec3_t v;
vec3_t crv;
beamseg_t *c;
particle_t *p;
particle_t *q;
float ts;
unsigned int colour;
int cb, cg, cr, ca;
// D3D_DrawParticleBeam(b, type);
// return;
if (lastgltype != type)
{
lastgltype = type;
pD3DDev->lpVtbl->SetTexture(pD3DDev, 0, NULL);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2);
APPLYD3DBLEND(type->blendmode);
}
c = b->next;
q = c->p;
p = b->p;
cr = q->rgb[0]*255;
if (cr < 0) cr = 0;
if (cr > 255) cr = 255;
cg = q->rgb[1]*255;
if (cg < 0) cg = 0;
if (cg > 255) cg = 255;
cb = q->rgb[2]*255;
if (cb < 0) cb = 0;
if (cb > 255) cb = 255;
ca = q->alpha*255;
if (ca < 0) ca = 0;
if (ca > 255) ca = 255;
colour = (cb) | (cg<<8) | (cr << 16) | (ca << 24);
c = b->next;
q = c->p;
p = b->p;
VectorSubtract(r_refdef.vieworg, q->org, v);
VectorNormalize(v);
CrossProduct(c->dir, v, crv);
ts = c->texture_s*type->rotationstartmin + particletime*type->rotationmin;
VectorMA(q->org, -q->scale, crv, d3dparticlevertut[0].org);
d3dparticlevertut[0].colour = colour;
VectorMA(q->org, q->scale, crv, d3dparticlevertut[1].org);
d3dparticlevertut[1].colour = colour;
cr = p->rgb[0]*255;
if (cr < 0) cr = 0;
if (cr > 255) cr = 255;
cg = p->rgb[1]*255;
if (cg < 0) cg = 0;
if (cg > 255) cg = 255;
cb = p->rgb[2]*255;
if (cb < 0) cb = 0;
if (cb > 255) cb = 255;
ca = p->alpha*255;
if (ca < 0) ca = 0;
if (ca > 255) ca = 255;
colour = (cb) | (cg<<8) | (cr << 16) | (ca << 24);
VectorSubtract(r_refdef.vieworg, p->org, v);
VectorNormalize(v);
CrossProduct(b->dir, v, crv); // replace with old p->dir?
ts = b->texture_s*type->rotationstartmin + particletime*type->rotationmin;
VectorMA(p->org, p->scale, crv, d3dparticlevertut[2].org);
d3dparticlevertut[2].colour = colour;
VectorMA(p->org, -p->scale, crv, d3dparticlevertut[3].org);
d3dparticlevertut[3].colour = colour;
pD3DDev->lpVtbl->DrawIndexedPrimitive(pD3DDev, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_DIFFUSE, d3dparticlevertut, 4, d3dparticlevertindexes, 6, 0);
}
#endif
void DrawParticleTypes (void (*texturedparticles)(particle_t *,part_type_t*), void (*sparklineparticles)(particle_t*,part_type_t*), void (*sparkfanparticles)(particle_t*,part_type_t*), void (*sparktexturedparticles)(particle_t*,part_type_t*), void (*beamparticlest)(beamseg_t*,part_type_t*), void (*beamparticlesut)(beamseg_t*,part_type_t*), void (*drawdecalparticles)(clippeddecal_t*,part_type_t*))
{
@ -4572,6 +4922,41 @@ void P_DrawParticles (void)
return;
}
#endif
#if defined(D3DQUAKE)
if (qrenderer == QR_DIRECT3D)
{
if (pD3DDev)
{
lastgltype = NULL;
DrawParticleTypes(D3D_DrawParticleBlob, D3D_DrawParticleSpark, D3D_DrawParticleSpark, D3D_DrawParticleSpark, D3D_DrawParticleBeam, D3D_DrawParticleBeamUT, NULL);
pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ZWRITEENABLE, FALSE );
pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHATESTENABLE, FALSE );
pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHABLENDENABLE, TRUE );
RSpeedRemark();
RQ_RenderDistAndClear();
RSpeedEnd(RSPEED_PARTICLESDRAW);
pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ZWRITEENABLE, TRUE );
pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHATESTENABLE, TRUE );
pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE );
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
return;
}
else
D3D9_DrawParticles(particletime);
}
#endif
if (qrenderer)
{
RSpeedRemark();
RQ_RenderDistAndClear();
RSpeedEnd(RSPEED_PARTICLESDRAW);
}
}

View file

@ -27,6 +27,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define TOP_RANGE (TOP_DEFAULT<<4)
#define BOTTOM_RANGE (BOTTOM_DEFAULT<<4)
extern int r_framecount;
struct msurface_s;
//=============================================================================
@ -266,15 +268,124 @@ void R_SetVrect (vrect_t *pvrect, vrect_t *pvrectin, int lineadj);
struct palremap_s *D_IdentityRemap(void);
//normalmaps
//bumpmaps
//32bits
//8bits
//8bitpal24
//8bitpal32
#define TF_NOMIPMAP 0x0000
#define TF_NOTBUMPMAP 0x0000
#define TF_NOALPHA 0x0000
#define TF_MIPMAP 0x0001
#define TF_BUMPMAP 0x0002 //or normalmap, depending on 8/24 bitness
#define TF_ALPHA 0x0004 //preserve alpha channel (8biit, use index 255 for transparency)
#define TF_FULLBRIGHT 0x0008 //dark pixels have alpha forced to 0
#define TF_24BIT 0x0010
#define TF_32BIT 0x0020 //use the standard quake palette
#define TF_MANDATORY (TF_NOMIPMAP|TF_NOTBUMPMAP|TF_NOALPHA)
#if 0
/*
int R_LoadTexture(char *name, int width, int height, void *data, void *palette, int flags)
{
if (palette)
{
if (flags & TF_BUMPMAP)
return 0; //huh?
if (flags & TF_FULLBRIGHT)
return 0; //huh?
if (flags & TF_32BIT)
return R_LoadTexture8Pal32(name, width, height, data, palette, flags&TF_MIPMAP, flags&TF_ALPHA);
return 0;
}
if (flags & TF_FULLBRIGHT)
{
if (flags & TF_BUMPMAP)
return 0; //huh?
if (flags & TF_24BIT)
return 0;
if (flags & TF_32BIT)
return 0;
//8bit fullbrights
return R_LoadTextureFB(name, width, height, data, flags&TF_MIPMAP, flags&TF_ALPHA);
}
if (flags & TF_BUMPMAP)
{
if (flags & TF_24BIT)
return 0;
if (flags & TF_32BIT)
return R_LoadTexture32(name, width, height, data, flags&TF_MIPMAP, flags&TF_ALPHA); //Warning: this is not correct
return R_LoadTexture8Bump(skinname,width,height,data,usemips,alpha) R_LoadTexture(name, width, height, data, NULL, TF_BUMPMAP | ((usemips)?TF_MIPMAP:TF_NOMIPMAP) | ((alpha)?TF_ALPHA:TF_NOALPHA))
}
if (flags & TF_32BIT)
return R_LoadTexture32(name, width, height, data, flags&TF_MIPMAP, flags&TF_ALPHA);
if (data)
return R_LoadTexture8(name, width, height, data, flags&TF_MIPMAP, flags&TF_ALPHA);
return R_FindTexture(name);
}
#define R_LoadTexture8Pal32(skinname,width,height,data,palette,usemips,alpha) R_LoadTexture(name, width, height, data, palette, TF_32BIT | ((usemips)?TF_MIPMAP:TF_NOMIPMAP) | ((alpha)?TF_ALPHA:TF_NOALPHA))
#define R_LoadTexture8(skinname,width,height,data,usemips,alpha) R_LoadTexture(name, width, height, data, NULL, ((usemips)?TF_MIPMAP:TF_NOMIPMAP) | ((alpha)?TF_ALPHA:TF_NOALPHA))
#define R_LoadTexture32(skinname,width,height,data,usemips,alpha) R_LoadTexture(name, width, height, data, NULL, TF_32BIT | ((usemips)?TF_MIPMAP:TF_NOMIPMAP) | ((alpha)?TF_ALPHA:TF_NOALPHA))
#define R_LoadTextureFB(skinname,width,height,data,usemips,alpha) R_LoadTexture(name, width, height, data, NULL, TF_FULLBRIGHT | ((usemips)?TF_MIPMAP:TF_NOMIPMAP) | ((alpha)?TF_ALPHA:TF_NOALPHA))
#define R_LoadTexture8Bump(skinname,width,height,data,usemips,alpha) R_LoadTexture(name, width, height, data, NULL, TF_BUMPMAP | ((usemips)?TF_MIPMAP:TF_NOMIPMAP) | ((alpha)?TF_ALPHA:TF_NOALPHA))
#define R_FindTexture(name) R_LoadTexture(name, 0, 0, NULL, NULL, 0)
#define R_LoadCompressed(name) ((qrenderer == QR_OPENGL)?GL_LoadCompressed(name):0)
*/
#elif defined(RGLQUAKE) && defined(D3DQUAKE)
#define R_LoadTexture8Pal32(skinname,width,height,data,palette,usemips,alpha) ((qrenderer == QR_DIRECT3D)?D3D_LoadTexture8Pal32(skinname, width, height, data, palette, usemips, alpha):GL_LoadTexture8Pal32(skinname, width, height, data, palette, usemips, alpha))
#define R_LoadTexture8Pal24(skinname,width,height,data,palette,usemips,alpha) ((qrenderer == QR_DIRECT3D)?D3D_LoadTexture8Pal24(skinname, width, height, data, palette, usemips, alpha):GL_LoadTexture8Pal24(skinname, width, height, data, palette, usemips, alpha))
#define R_LoadTexture8(skinname,width,height,data,usemips,alpha) ((qrenderer == QR_DIRECT3D)?D3D_LoadTexture(skinname, width, height, data, usemips, alpha):GL_LoadTexture(skinname, width, height, data, usemips, alpha))
#define R_LoadTexture32(skinname,width,height,data,usemips,alpha) ((qrenderer == QR_DIRECT3D)?D3D_LoadTexture32(skinname, width, height, data, usemips, alpha):GL_LoadTexture32(skinname, width, height, data, usemips, alpha))
#define R_LoadTextureFB(skinname,width,height,data,usemips,alpha) ((qrenderer == QR_DIRECT3D)?D3D_LoadTextureFB(skinname, width, height, data, usemips, alpha):GL_LoadTextureFB(skinname, width, height, data, usemips, alpha))
#define R_LoadTexture8Bump(skinname,width,height,data,usemips,alpha) ((qrenderer == QR_DIRECT3D)?/*D3D_LoadTexture8Bump(skinname, width, height, data, usemips, alpha)*/NULL:GL_LoadTexture8Bump(skinname, width, height, data, usemips, alpha))
#define R_FindTexture(name) ((qrenderer == QR_DIRECT3D)?D3D_FindTexture(name):GL_FindTexture(name))
#define R_LoadCompressed(name) ((qrenderer == QR_DIRECT3D)?D3D_LoadCompressed(name):GL_LoadCompressed(name))
#elif defined(D3DQUAKE)
#define R_LoadTexture8Pal32 D3D_LoadTexture8Pal32
#define R_LoadTexture8 D3D_LoadTexture
#define R_LoadTexture32 D3D_LoadTexture32
#define R_LoadTextureFB D3D_LoadTextureFB
#define R_LoadTexture8Bump D3D_LoadTexture8Bump
#define R_FindTexture D3D_FindTexture
#define R_LoadCompressed D3D_LoadCompressed
#elif defined(RGLQUAKE)
#define R_LoadTexture8Pal32 GL_LoadTexture8Pal32
#define R_LoadTexture8 GL_LoadTexture
#define R_LoadTexture32 GL_LoadTexture32
#define R_LoadTextureFB GL_LoadTextureFB
#define R_LoadTexture8Bump GL_LoadTexture8Bump
#define R_FindTexture GL_FindTexture
#define R_LoadCompressed GL_LoadCompressed
#endif
#if defined(RGLQUAKE)
#if defined(RGLQUAKE) || defined(D3DQUAKE)
void GLMod_Init (void);
qboolean GLMod_GetTag(struct model_s *model, int tagnum, int frame, int frame2, float f2ness, float f1time, float f2time, float *result);
int GLMod_TagNumForName(struct model_s *model, char *name);
int GLMod_SkinNumForName(struct model_s *model, char *name);
qboolean Mod_GetTag(struct model_s *model, int tagnum, int frame, int frame2, float f2ness, float f1time, float f2time, float *result);
int Mod_TagNumForName(struct model_s *model, char *name);
int Mod_SkinNumForName(struct model_s *model, char *name);
void GLMod_ClearAll (void);
struct model_s *GLMod_ForName (char *name, qboolean crash);

View file

@ -35,6 +35,7 @@ void GL_Texture_Anisotropic_Filtering_Callback (struct cvar_s *var, char *oldval
//
cvar_t r_novis = SCVAR("r_novis", "0");
cvar_t r_drawviewmodel = SCVAR("r_drawviewmodel","1");
cvar_t r_drawviewmodelinvis = SCVAR("r_drawviewmodelinvis", "0");
cvar_t r_netgraph = SCVAR("r_netgraph","0");
@ -139,7 +140,7 @@ cvar_t gl_compress = SCVARF("gl_compress", "0", CVAR_ARCHIVE);
cvar_t gl_savecompressedtex = SCVAR("gl_savecompressedtex", "0");
extern cvar_t gl_dither;
extern cvar_t gl_maxdist;
extern cvar_t gl_mindist;
cvar_t gl_mindist = SCVARF("gl_mindist", "4", CVAR_CHEAT); //by setting to 64 or something, you can use this as a wallhack
cvar_t gl_detail = SCVARF("gl_detail", "0", CVAR_ARCHIVE);
@ -259,6 +260,13 @@ cvar_t r_fastskycolour = SCVAR("r_fastskycolour", "0");
cvar_t r_menutint = SCVARF("r_menutint", "0.68 0.4 0.13", CVAR_RENDERERCALLBACK);
#if defined(RGLQUAKE) || defined(D3DQUAKE)
void GLD3DRenderer_Init(void)
{
Cvar_Register (&gl_load24bit, GRAPHICALNICETIES);
}
#endif
#if defined(RGLQUAKE)
cvar_t gl_schematics = SCVAR("gl_schematics","0");
cvar_t gl_ztrick = SCVAR("gl_ztrick","0");
@ -280,7 +288,6 @@ void GLRenderer_Init(void)
Cvar_Register (&vid_desktopgamma, GLRENDEREROPTIONS);
//renderer
Cvar_Register (&r_novis, GLRENDEREROPTIONS);
Cvar_Register (&r_mirroralpha, GLRENDEREROPTIONS);
Cvar_Register (&r_norefresh, GLRENDEREROPTIONS);
@ -333,7 +340,6 @@ void GLRenderer_Init(void)
#ifdef R_XFLIP
Cvar_Register (&r_xflip, GLRENDEREROPTIONS);
#endif
Cvar_Register (&gl_load24bit, GRAPHICALNICETIES);
Cvar_Register (&gl_specular, GRAPHICALNICETIES);
// Cvar_Register (&gl_lightmapmode, GLRENDEREROPTIONS);
@ -476,6 +482,9 @@ void Renderer_Init(void)
Cmd_AddCommand("setrenderer", R_SetRenderer_f);
Cmd_AddCommand("vid_restart", R_RestartRenderer_f);
#if defined(RGLQUAKE) || defined(D3DQUAKE)
GLD3DRenderer_Init();
#endif
#if defined(RGLQUAKE)
GLRenderer_Init();
#endif
@ -483,6 +492,8 @@ void Renderer_Init(void)
SWRenderer_Init();
#endif
Cvar_Register (&r_novis, GLRENDEREROPTIONS);
//but register ALL vid_ commands.
Cvar_Register (&_vid_wait_override, VIDCOMMANDGROUP);
Cvar_Register (&vid_stretch, VIDCOMMANDGROUP);
@ -662,8 +673,8 @@ void (*Mod_TouchModel) (char *name);
void (*Mod_NowLoadExternal) (void);
void (*Mod_Think) (void);
qboolean (*Mod_GetTag) (struct model_s *model, int tagnum, int frame, int frame2, float f2ness, float f1time, float f2time, float *transforms);
int (*Mod_TagNumForName) (struct model_s *model, char *name);
//qboolean (*Mod_GetTag) (struct model_s *model, int tagnum, int frame, int frame2, float f2ness, float f1time, float f2time, float *transforms);
//int (*Mod_TagNumForName) (struct model_s *model, char *name);
int (*Mod_SkinForName) (struct model_s *model, char *name);
@ -759,7 +770,7 @@ rendererinfo_t dedicatedrendererinfo = {
SWMod_NowLoadExternal,
SWMod_Think,
#elif defined(RGLQUAKE)
#elif defined(RGLQUAKE) || defined(D3DQUAKE)
GLMod_Init,
GLMod_ClearAll,
GLMod_ForName,
@ -770,7 +781,7 @@ rendererinfo_t dedicatedrendererinfo = {
GLMod_NowLoadExternal,
GLMod_Think,
#else
#error "No renderer in client build"
#error "Need logic here!"
#endif
NULL, //Mod_GetTag
@ -963,9 +974,9 @@ rendererinfo_t openglrendererinfo = {
GLMod_NowLoadExternal,
GLMod_Think,
GLMod_GetTag,
GLMod_TagNumForName,
GLMod_SkinNumForName,
Mod_GetTag,
Mod_TagNumForName,
Mod_SkinNumForName,
GLVID_Init,
GLVID_DeInit,
@ -990,8 +1001,16 @@ rendererinfo_t openglrendererinfo = {
rendererinfo_t *popenglrendererinfo = &openglrendererinfo;
#endif
#ifdef D3DQUAKE
rendererinfo_t d3d7rendererinfo;
rendererinfo_t *pd3d7rendererinfo = &d3d7rendererinfo;
#endif
rendererinfo_t *pd3drendererinfo;
rendererinfo_t d3d9rendererinfo;
rendererinfo_t *pd3d9rendererinfo = &d3d9rendererinfo;
rendererinfo_t **rendererinfo[] =
{
&pdedicatedrendererinfo,
@ -1002,6 +1021,12 @@ rendererinfo_t **rendererinfo[] =
&popenglrendererinfo,
&pd3drendererinfo,
#endif
#ifdef D3DQUAKE
&pd3d7rendererinfo,
#endif
#ifdef D3DQUAKE
&pd3d9rendererinfo,
#endif
};
@ -1190,6 +1215,9 @@ void M_Menu_Video_f (void)
#ifdef USE_D3D
"Direct3D",
#endif
#endif
#ifdef D3DQUAKE
"NDirect3D",
#endif
NULL
};
@ -1298,12 +1326,12 @@ void M_Menu_Video_f (void)
MC_AddCheckBox(menu, 16, y, " Bloom", &r_bloom,0); y+=8;
#endif
MC_AddCheckBox(menu, 16, y, " Dynamic lights", &r_dynamic,0); y+=8;
MC_AddSlider(menu, 16, y, " Screen size", &scr_viewsize, 30, 120);y+=8;
MC_AddSlider(menu, 16, y, " Gamma", &v_gamma, 0.3, 1); y+=8;
MC_AddSlider(menu, 16, y, " Contrast", &v_contrast, 1, 3); y+=8;
MC_AddSlider(menu, 16, y, " Screen size", &scr_viewsize, 30, 120, 0.1);y+=8;
MC_AddSlider(menu, 16, y, " Gamma", &v_gamma, 0.3, 1, 0.05); y+=8;
MC_AddSlider(menu, 16, y, " Contrast", &v_contrast, 1, 3, 0.05); y+=8;
#ifdef RGLQUAKE
info->texturefiltercombo = MC_AddCombo(menu, 16, y, " Texture Filter ", texturefilternames, currenttexturefilter); y+=8;
MC_AddSlider(menu, 16, y, "Anisotropy Level", &gl_texture_anisotropic_filtering, 1, 16); y+=8;
MC_AddSlider(menu, 16, y, "Anisotropy Level", &gl_texture_anisotropic_filtering, 1, 16, 1); y+=8; //urm, this shouldn't really be a slider, but should be a combo instead
#endif
menu->cursoritem = (menuoption_t*)MC_AddWhiteText(menu, 152, 32, NULL, false);
@ -1398,8 +1426,8 @@ void R_SetRenderer(int wanted)
Mod_NowLoadExternal = ri->Mod_NowLoadExternal;
Mod_GetTag = ri->Mod_GetTag;
Mod_TagNumForName = ri->Mod_TagNumForName;
// Mod_GetTag = ri->Mod_GetTag;
// Mod_TagNumForName = ri->Mod_TagNumForName;
Mod_SkinForName = ri->Mod_SkinForName;
SCR_UpdateScreen = ri->SCR_UpdateScreen;
@ -1419,6 +1447,15 @@ qbyte default_conchar[11356] =
#include "lhfont.h"
};
qboolean R_ApplyRenderer_Load (rendererstate_t *newr);
void D3DSucks(void)
{
SCR_DeInit();
if (!R_ApplyRenderer_Load(NULL))//&currentrendererstate))
Sys_Error("Failed to reload content after mode switch\n");
}
qboolean R_ApplyRenderer (rendererstate_t *newr)
{
int i, j;
@ -1461,6 +1498,14 @@ qboolean R_ApplyRenderer (rendererstate_t *newr)
R_SetRenderer(newr->renderer);
R_ApplyRenderer_Load(newr);
}
qboolean R_ApplyRenderer_Load (rendererstate_t *newr)
{
int i, j;
extern model_t *loadmodel;
extern int host_hunklevel;
Cache_Flush();
Hunk_FreeToLowMark(host_hunklevel); //is this a good idea?
@ -1475,7 +1520,8 @@ qboolean R_ApplyRenderer (rendererstate_t *newr)
#ifndef CLIENTONLY
isDedicated = false;
#endif
Con_Printf("Setting mode %i*%i*%i*%i\n", newr->width, newr->height, newr->bpp, newr->rate);
if (newr)
Con_Printf("Setting mode %i*%i*%i*%i\n", newr->width, newr->height, newr->bpp, newr->rate);
if (host_basepal)
BZ_Free(host_basepal);
@ -1544,10 +1590,19 @@ q2colormap:
TRACE(("dbg: R_ApplyRenderer: Palette loaded\n"));
if (!VID_Init(newr, host_basepal))
#ifdef _WIN32
if (hwnd_dialog)
{
return false;
DestroyWindow (hwnd_dialog);
hwnd_dialog = NULL;
}
#endif
if (newr)
if (!VID_Init(newr, host_basepal))
{
return false;
}
TRACE(("dbg: R_ApplyRenderer: vid applied\n"));
W_LoadWadFile("gfx.wad");
@ -1799,6 +1854,12 @@ TRACE(("dbg: R_ApplyRenderer: efrags\n"));
"-----------------------------\n"
"OpenGL renderer initialized\n");
break;
case QR_DIRECT3D:
Con_Printf( "\n"
"-----------------------------\n"
"Direct3d renderer initialized\n");
break;
}
TRACE(("dbg: R_ApplyRenderer: S_Restart_f\n"));
@ -1807,7 +1868,8 @@ TRACE(("dbg: R_ApplyRenderer: efrags\n"));
TRACE(("dbg: R_ApplyRenderer: done\n"));
memcpy(&currentrendererstate, newr, sizeof(currentrendererstate));
if (newr)
memcpy(&currentrendererstate, newr, sizeof(currentrendererstate));
return true;
}
@ -1865,6 +1927,8 @@ TRACE(("dbg: R_RestartRenderer_f\n"));
#elif defined(RGLQUAKE)
Cmd_ExecuteString("setrenderer gl\n", RESTRICT_LOCAL);
#elif defined(D3DQUAKE)
Cmd_ExecuteString("setrenderer d3d\n", RESTRICT_LOCAL);
#else
Cmd_ExecuteString("setrenderer sw\n", RESTRICT_LOCAL);
#endif
@ -2014,3 +2078,558 @@ void R_SetRenderer_f (void)
/*
================
R_GetSpriteFrame
================
*/
mspriteframe_t *R_GetSpriteFrame (entity_t *currententity)
{
msprite_t *psprite;
mspritegroup_t *pspritegroup;
mspriteframe_t *pspriteframe;
int i, numframes, frame;
float *pintervals, fullinterval, targettime, time;
psprite = currententity->model->cache.data;
frame = currententity->frame;
if ((frame >= psprite->numframes) || (frame < 0))
{
Con_DPrintf ("R_DrawSprite: no such frame %d (%s)\n", frame, currententity->model->name);
frame = 0;
}
if (psprite->frames[frame].type == SPR_SINGLE)
{
pspriteframe = psprite->frames[frame].frameptr;
}
else if (psprite->frames[frame].type == SPR_ANGLED)
{
pspritegroup = (mspritegroup_t *)psprite->frames[frame].frameptr;
pspriteframe = pspritegroup->frames[(int)((r_refdef.viewangles[1]-currententity->angles[1])/360*8 + 0.5-4)&7];
}
else
{
pspritegroup = (mspritegroup_t *)psprite->frames[frame].frameptr;
pintervals = pspritegroup->intervals;
numframes = pspritegroup->numframes;
fullinterval = pintervals[numframes-1];
time = currententity->frame1time;
// when loading in Mod_LoadSpriteGroup, we guaranteed all interval values
// are positive, so we don't have to worry about division by 0
targettime = time - ((int)(time / fullinterval)) * fullinterval;
for (i=0 ; i<(numframes-1) ; i++)
{
if (pintervals[i] > targettime)
break;
}
pspriteframe = pspritegroup->frames[i];
}
return pspriteframe;
}
float r_projection_matrix[16];
float r_view_matrix[16];
void MYgluPerspective(double fovx, double fovy, double zNear, double zFar)
{
double xmin, xmax, ymin, ymax;
ymax = zNear * tan( fovy * M_PI / 360.0 );
ymin = -ymax;
xmax = zNear * tan( fovx * M_PI / 360.0 );
xmin = -xmax;
r_projection_matrix[0] = (2*zNear) / (xmax - xmin);
r_projection_matrix[4] = 0;
r_projection_matrix[8] = (xmax + xmin) / (xmax - xmin);
r_projection_matrix[12] = 0;
r_projection_matrix[1] = 0;
r_projection_matrix[5] = (2*zNear) / (ymax - ymin);
r_projection_matrix[9] = (ymax + ymin) / (ymax - ymin);
r_projection_matrix[13] = 0;
r_projection_matrix[2] = 0;
r_projection_matrix[6] = 0;
r_projection_matrix[10] = - (zFar+zNear)/(zFar-zNear);
r_projection_matrix[14] = - (2.0f*zFar*zNear)/(zFar-zNear);
r_projection_matrix[3] = 0;
r_projection_matrix[7] = 0;
r_projection_matrix[11] = -1;
r_projection_matrix[15] = 0;
}
void GL_InfinatePerspective(double fovx, double fovy,
double zNear)
{
// nudge infinity in just slightly for lsb slop
float nudge = 1;// - 1.0 / (1<<23);
double xmin, xmax, ymin, ymax;
ymax = zNear * tan( fovy * M_PI / 360.0 );
ymin = -ymax;
xmax = zNear * tan( fovx * M_PI / 360.0 );
xmin = -xmax;
r_projection_matrix[0] = (2*zNear) / (xmax - xmin);
r_projection_matrix[4] = 0;
r_projection_matrix[8] = (xmax + xmin) / (xmax - xmin);
r_projection_matrix[12] = 0;
r_projection_matrix[1] = 0;
r_projection_matrix[5] = (2*zNear) / (ymax - ymin);
r_projection_matrix[9] = (ymax + ymin) / (ymax - ymin);
r_projection_matrix[13] = 0;
r_projection_matrix[2] = 0;
r_projection_matrix[6] = 0;
r_projection_matrix[10] = -1 * nudge;
r_projection_matrix[14] = -2*zNear * nudge;
r_projection_matrix[3] = 0;
r_projection_matrix[7] = 0;
r_projection_matrix[11] = -1;
r_projection_matrix[15] = 0;
}
void GL_ParallelPerspective(double xmin, double xmax, double ymax, double ymin,
double znear, double zfar)
{
r_projection_matrix[0] = 2/(xmax-xmin);
r_projection_matrix[4] = 0;
r_projection_matrix[8] = 0;
r_projection_matrix[12] = (xmax+xmin)/(xmax-xmin);
r_projection_matrix[1] = 0;
r_projection_matrix[5] = 2/(ymax-ymin);
r_projection_matrix[9] = 0;
r_projection_matrix[13] = (ymax+ymin)/(ymax-ymin);
r_projection_matrix[2] = 0;
r_projection_matrix[6] = 0;
r_projection_matrix[10] = -2/(zfar-znear);
r_projection_matrix[14] = (zfar+znear)/(zfar-znear);
r_projection_matrix[3] = 0;
r_projection_matrix[7] = 0;
r_projection_matrix[11] = 0;
r_projection_matrix[15] = 1;
}
/*
===============
R_TextureAnimation
Returns the proper texture for a given time and base texture
===============
*/
extern entity_t *currententity;
texture_t *R_TextureAnimation (texture_t *base)
{
int reletive;
int count;
if (currententity->frame)
{
if (base->alternate_anims)
base = base->alternate_anims;
}
if (!base->anim_total)
return base;
reletive = (int)(cl.time*10) % base->anim_total;
count = 0;
while (base->anim_min > reletive || base->anim_max <= reletive)
{
base = base->anim_next;
if (!base)
Sys_Error ("R_TextureAnimation: broken cycle");
if (++count > 100)
Sys_Error ("R_TextureAnimation: infinite cycle");
}
return base;
}
extern mleaf_t *r_viewleaf, *r_oldviewleaf;
extern mleaf_t *r_viewleaf2, *r_oldviewleaf2;
extern int r_viewcluster, r_viewcluster2, r_oldviewcluster, r_oldviewcluster2;
extern int r_visframecount;
extern mleaf_t *r_vischain; // linked list of visible leafs
/*
===============
R_MarkLeaves
===============
*/
void R_MarkLeaves (void)
{
qbyte fatvis[MAX_MAP_LEAFS/8];
qbyte *vis;
mnode_t *node;
int i;
qbyte solid[4096];
#ifdef Q3BSPS
if (cl.worldmodel->fromgame == fg_quake3)
{
int cluster;
mleaf_t *leaf;
if (r_oldviewcluster == r_viewcluster && !r_novis.value && r_viewcluster != -1)
return;
// development aid to let you run around and see exactly where
// the pvs ends
// if (r_lockpvs->value)
// return;
r_vischain = NULL;
r_visframecount++;
r_oldviewcluster = r_viewcluster;
if (r_novis.value || r_viewcluster == -1 || !cl.worldmodel->vis )
{
// mark everything
for (i=0,leaf=cl.worldmodel->leafs ; i<cl.worldmodel->numleafs ; i++, leaf++)
{
if ( !leaf->nummarksurfaces ) {
continue;
}
leaf->visframe = r_visframecount;
leaf->vischain = r_vischain;
r_vischain = leaf;
}
return;
}
vis = CM_ClusterPVS (cl.worldmodel, r_viewcluster, NULL);//, cl.worldmodel);
for (i=0,leaf=cl.worldmodel->leafs ; i<cl.worldmodel->numleafs ; i++, leaf++)
{
cluster = leaf->cluster;
if ( cluster == -1 || !leaf->nummarksurfaces ) {
continue;
}
if ( vis[cluster>>3] & (1<<(cluster&7)) ) {
leaf->visframe = r_visframecount;
leaf->vischain = r_vischain;
r_vischain = leaf;
}
}
return;
}
#endif
#ifdef Q2BSPS
if (cl.worldmodel->fromgame == fg_quake2)
{
int c;
mleaf_t *leaf;
int cluster;
if (r_oldviewcluster == r_viewcluster && r_oldviewcluster2 == r_viewcluster2)
return;
r_oldviewcluster = r_viewcluster;
r_oldviewcluster2 = r_viewcluster2;
if (r_novis.value == 2)
return;
r_visframecount++;
if (r_novis.value || r_viewcluster == -1 || !cl.worldmodel->vis)
{
// mark everything
for (i=0 ; i<cl.worldmodel->numleafs ; i++)
cl.worldmodel->leafs[i].visframe = r_visframecount;
for (i=0 ; i<cl.worldmodel->numnodes ; i++)
cl.worldmodel->nodes[i].visframe = r_visframecount;
return;
}
vis = CM_ClusterPVS (cl.worldmodel, r_viewcluster, NULL);//, cl.worldmodel);
// may have to combine two clusters because of solid water boundaries
if (r_viewcluster2 != r_viewcluster)
{
memcpy (fatvis, vis, (cl.worldmodel->numleafs+7)/8);
vis = CM_ClusterPVS (cl.worldmodel, r_viewcluster2, NULL);//, cl.worldmodel);
c = (cl.worldmodel->numleafs+31)/32;
for (i=0 ; i<c ; i++)
((int *)fatvis)[i] |= ((int *)vis)[i];
vis = fatvis;
}
for (i=0,leaf=cl.worldmodel->leafs ; i<cl.worldmodel->numleafs ; i++, leaf++)
{
cluster = leaf->cluster;
if (cluster == -1)
continue;
if (vis[cluster>>3] & (1<<(cluster&7)))
{
node = (mnode_t *)leaf;
do
{
if (node->visframe == r_visframecount)
break;
node->visframe = r_visframecount;
node = node->parent;
} while (node);
}
}
return;
}
#endif
if (((r_oldviewleaf == r_viewleaf && r_oldviewleaf2 == r_viewleaf2) && !r_novis.value) || r_novis.value == 2)
return;
// if (mirror)
// return;
r_visframecount++;
r_oldviewleaf = r_viewleaf;
r_oldviewleaf2 = r_viewleaf2;
if (r_novis.value)
{
vis = solid;
memset (solid, 0xff, (cl.worldmodel->numleafs+7)>>3);
}
else if (r_viewleaf2)
{
int c;
Q1BSP_LeafPVS (cl.worldmodel, r_viewleaf2, fatvis);
vis = Q1BSP_LeafPVS (cl.worldmodel, r_viewleaf, NULL);
c = (cl.worldmodel->numleafs+31)/32;
for (i=0 ; i<c ; i++)
((int *)fatvis)[i] |= ((int *)vis)[i];
vis = fatvis;
}
else
vis = Q1BSP_LeafPVS (cl.worldmodel, r_viewleaf, NULL);
for (i=0 ; i<cl.worldmodel->numleafs ; i++)
{
if (vis[i>>3] & (1<<(i&7)))
{
node = (mnode_t *)&cl.worldmodel->leafs[i+1];
do
{
if (node->visframe == r_visframecount)
break;
node->visframe = r_visframecount;
node = node->parent;
} while (node);
}
}
}
mplane_t frustum[4];
/*
=================
R_CullBox
Returns true if the box is completely outside the frustom
=================
*/
qboolean R_CullBox (vec3_t mins, vec3_t maxs)
{
int i;
for (i=0 ; i<4 ; i++)
if (BOX_ON_PLANE_SIDE (mins, maxs, &frustum[i]) == 2)
return true;
return false;
}
qboolean R_CullSphere (vec3_t org, float radius)
{
//four frustrum planes all point inwards in an expanding 'cone'.
int i;
float d;
for (i=0 ; i<4 ; i++)
{
d = DotProduct(frustum[i].normal, org)-frustum[i].dist;
if (d <= -radius)
return true;
}
return false;
}
qboolean R_CullEntityBox(entity_t *e, vec3_t modmins, vec3_t modmaxs)
{
int i;
vec3_t wmin, wmax;
float fmin, fmax;
//convert the model's bbox to the expanded maximum size of the entity, as drawn with this model.
//The result is an axial box, which we pass to R_CullBox
for (i = 0; i < 3; i++)
{
fmin = DotProduct(modmins, e->axis[i]);
fmax = DotProduct(modmaxs, e->axis[i]);
if (fmin > -16)
fmin = -16;
if (fmax < 16)
fmax = 16;
if (fmin < fmax)
{
wmin[i] = e->origin[i]+fmin;
wmax[i] = e->origin[i]+fmax;
}
else
{ //box went inside out
wmin[i] = e->origin[i]+fmax;
wmax[i] = e->origin[i]+fmin;
}
}
return R_CullBox(wmin, wmax);
}
int SignbitsForPlane (mplane_t *out)
{
int bits, j;
// for fast box on planeside test
bits = 0;
for (j=0 ; j<3 ; j++)
{
if (out->normal[j] < 0)
bits |= 1<<j;
}
return bits;
}
#if 1
void R_SetFrustum (void)
{
float scale;
int i;
float mvp[16];
if ((int)r_novis.value & 4)
return;
Matrix4_Multiply(r_projection_matrix, r_view_matrix, mvp);
for (i = 0; i < 4; i++)
{
if (i & 1)
{
frustum[i].normal[0] = mvp[3] + mvp[0+i/2];
frustum[i].normal[1] = mvp[7] + mvp[4+i/2];
frustum[i].normal[2] = mvp[11] + mvp[8+i/2];
frustum[i].dist = mvp[15] + mvp[12+i/2];
}
else
{
frustum[i].normal[0] = mvp[3] - mvp[0+i/2];
frustum[i].normal[1] = mvp[7] - mvp[4+i/2];
frustum[i].normal[2] = mvp[11] - mvp[8+i/2];
frustum[i].dist = mvp[15] - mvp[12+i/2];
}
scale = 1/sqrt(DotProduct(frustum[i].normal, frustum[i].normal));
frustum[i].normal[0] *= scale;
frustum[i].normal[1] *= scale;
frustum[i].normal[2] *= scale;
frustum[i].dist *= -scale;
frustum[i].type = PLANE_ANYZ;
frustum[i].signbits = SignbitsForPlane (&frustum[i]);
}
}
#else
void R_SetFrustum (void)
{
int i;
if ((int)r_novis.value & 4)
return;
/* removed - assumes fov_x == fov_y
if (r_refdef.fov_x == 90)
{
// front side is visible
VectorAdd (vpn, vright, frustum[0].normal);
VectorSubtract (vpn, vright, frustum[1].normal);
VectorAdd (vpn, vup, frustum[2].normal);
VectorSubtract (vpn, vup, frustum[3].normal);
}
else
*/
{
// rotate VPN right by FOV_X/2 degrees
RotatePointAroundVector( frustum[0].normal, vup, vpn, -(90-r_refdef.fov_x / 2 ) );
// rotate VPN left by FOV_X/2 degrees
RotatePointAroundVector( frustum[1].normal, vup, vpn, 90-r_refdef.fov_x / 2 );
// rotate VPN up by FOV_X/2 degrees
RotatePointAroundVector( frustum[2].normal, vright, vpn, 90-r_refdef.fov_y / 2 );
// rotate VPN down by FOV_X/2 degrees
RotatePointAroundVector( frustum[3].normal, vright, vpn, -( 90 - r_refdef.fov_y / 2 ) );
}
for (i=0 ; i<4 ; i++)
{
frustum[i].type = PLANE_ANYZ;
frustum[i].dist = DotProduct (r_origin, frustum[i].normal);
frustum[i].signbits = SignbitsForPlane (&frustum[i]);
}
}
#endif

View file

@ -2410,6 +2410,11 @@ void Sbar_CoopIntermission (void)
int dig;
int num;
sbar_rect.width = vid.width;
sbar_rect.height = vid.height;
sbar_rect.x = 0;
sbar_rect.y = 0;
scr_copyeverything = 1;
scr_fullupdate = 0;
@ -2453,6 +2458,9 @@ void Sbar_IntermissionOverlay (void)
if (UI_DrawIntermission()>0)
return;
#endif
Sbar_Start();
if (cls.gamemode != GAME_DEATHMATCH)
Sbar_CoopIntermission();
else if (cl.teamplay > 0 && !sb_showscores)

View file

@ -91,6 +91,6 @@ void SCR_ShowPic_Clear(void);
//a header is better than none...
void Draw_TextBox (int x, int y, int width, int lines);
void SCR_ScreenShot (char *filename);
qboolean SCR_ScreenShot (char *filename);
void SCR_DrawTwoDimensional(int uimenu, qboolean nohud);

View file

@ -20,6 +20,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "quakedef.h"
#include "winquake.h"
#include <dsound.h>
#define SND_ERROR 0
#define SND_LOADED 1
#define SND_NOMORE 2 //like error, but doesn't try the next card.

View file

@ -25,7 +25,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// a pixel can be one, two, or four bytes
typedef qbyte pixel_t;
typedef enum {QR_NONE, QR_SOFTWARE, QR_OPENGL} r_qrenderer_t;
typedef enum {QR_NONE, QR_SOFTWARE, QR_OPENGL, QR_DIRECT3D} r_qrenderer_t;
typedef struct {
//you are not allowed to make anything not work if it's not based on these vars...
@ -59,10 +59,12 @@ typedef struct
float aspect; // width / height -- < 0 is taller than wide
int numpages;
int recalc_refdef; // if true, recalc vid-based stuff
pixel_t *conbuffer;
int conrowbytes;
unsigned conwidth;
unsigned conheight;
int maxwarpwidth;
int maxwarpheight;
pixel_t *direct; // direct drawing to framebuffer, if not
@ -143,5 +145,6 @@ int SWVID_ForceUnlockedAndReturnState (void);
void SWVID_ForceLockState (int lk);
char *SWVID_GetRGBInfo(int prepadbytes, int *truewidth, int *trueheight);
void SWVID_SetCaption(char *caption);
#endif

View file

@ -374,7 +374,7 @@ void SWV_Gamma_Callback(struct cvar_s *var, char *oldvalue)
}
#endif
#ifdef RGLQUAKE
#if defined(RGLQUAKE) || defined(D3DQUAKE)
void GLV_Gamma_Callback(struct cvar_s *var, char *oldvalue)
{
BuildGammaTable (v_gamma.value, v_contrast.value);
@ -610,7 +610,7 @@ void V_CalcPowerupCshift (void)
V_CalcBlend
=============
*/
#if defined(RGLQUAKE)
#if defined(RGLQUAKE) || defined(D3DQUAKE)
void GLV_CalcBlendServer (float colors[4])
{
@ -1299,7 +1299,6 @@ void SCR_VRectForPlayer(vrect_t *vrect, int pnum)
r_refdef.fov_y = CalcFov(r_refdef.fov_x, vrect->width, vrect->height);
}
void ML_Project(vec3_t in, vec3_t out, vec3_t viewangles, vec3_t vieworg, float wdivh, float fovy);
void R_DrawNameTags(void)
{
int i;
@ -1332,7 +1331,7 @@ void R_DrawNameTags(void)
{
VectorCopy(state->origin, tagcenter);
tagcenter[2] += 32;
ML_Project(tagcenter, center, r_refdef.viewangles, r_refdef.vieworg, (float)r_refdef.vrect.width/r_refdef.vrect.height, r_refdef.fov_y);
Matrix4_Project(tagcenter, center, r_refdef.viewangles, r_refdef.vieworg, (float)r_refdef.vrect.width/r_refdef.vrect.height, r_refdef.fov_y);
if (center[2] > 1)
continue;
Draw_FunString(center[0]*r_refdef.vrect.width+r_refdef.vrect.x, (1-center[1])*r_refdef.vrect.height+r_refdef.vrect.y, cl.players[i].name);

View file

@ -49,7 +49,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef SERVERONLY
#ifndef NODIRECTX
#include <ddraw.h>
#include <dsound.h>
#endif
#ifdef SWQUAKE
#ifdef MGL

View file

@ -1185,7 +1185,7 @@ char *MSG_ReadString (void)
do
{
c = MSG_ReadChar ();
if (c == -1 || c == 0)
if (msg_badread || c == 0)
break;
string[l] = c;
l++;
@ -1205,7 +1205,7 @@ char *MSG_ReadStringLine (void)
do
{
c = MSG_ReadChar ();
if (c == -1 || c == 0 || c == '\n')
if (msg_badread || c == 0 || c == '\n')
break;
string[l] = c;
l++;

View file

@ -3,6 +3,9 @@
#include "glquake.h"
#include "shader.h"
#endif
#ifdef D3DQUAKE
#include "d3dquake.h"
#endif
#define MAX_Q3MAP_INDICES 0x80000
#define MAX_Q3MAP_VERTEXES 0x80000
@ -1067,7 +1070,7 @@ void *Mod_LoadWall(char *name)
if (in) //this is a pcx.
{
#ifdef RGLQUAKE
if (qrenderer == QR_OPENGL)
if (qrenderer == QR_OPENGL || qrenderer == QR_DIRECT3D)
{
tex = Hunk_AllocName(sizeof(texture_t), ln);
@ -1075,11 +1078,9 @@ void *Mod_LoadWall(char *name)
tex->width = width;
tex->height = height;
texture_mode = GL_LINEAR_MIPMAP_NEAREST; //_LINEAR;
if (!(tex->gl_texturenum = Mod_LoadReplacementTexture(name, loadname, true, false, true)))
if (!(tex->gl_texturenum = Mod_LoadReplacementTexture(name, "bmodels", true, false, true)))
tex->gl_texturenum = GL_LoadTexture32 (name, width, height, (unsigned int *)in, true, false);
texture_mode = GL_LINEAR;
}
else
#endif
@ -1148,8 +1149,8 @@ void *Mod_LoadWall(char *name)
return tex;
}
#if defined(RGLQUAKE)
if (qrenderer == QR_OPENGL)
#if defined(RGLQUAKE) || defined(D3DQUAKE)
if (qrenderer == QR_OPENGL || qrenderer == QR_DIRECT3D)
{
int j;
tex = Hunk_AllocName(sizeof(texture_t), ln);
@ -1158,17 +1159,15 @@ void *Mod_LoadWall(char *name)
tex->width = wal->width;
tex->height = wal->height;
texture_mode = GL_LINEAR_MIPMAP_NEAREST; //_LINEAR;
if (!(tex->gl_texturenum = Mod_LoadReplacementTexture(wal->name, loadname, true, false, true)))
if (!(tex->gl_texturenum = Mod_LoadReplacementTexture(wal->name, "bmodels", true, false, true)))
tex->gl_texturenum = GL_LoadTexture8Pal24 (wal->name, tex->width, tex->height, (qbyte *)wal+wal->offsets[0], d_q28to24table, true, false);
tex->gl_texturenum = R_LoadTexture8Pal24 (wal->name, tex->width, tex->height, (qbyte *)wal+wal->offsets[0], d_q28to24table, true, false);
in = Hunk_TempAllocMore(wal->width*wal->height);
oin = (qbyte *)wal+wal->offsets[0];
for (j = 0; j < wal->width*wal->height; j++)
in[j] = (d_q28to24table[oin[j]*3+0] + d_q28to24table[oin[j]*3+1] + d_q28to24table[oin[j]*3+2])/3;
tex->gl_texturenumbumpmap = GL_LoadTexture8Bump (va("%s_bump", wal->name), tex->width, tex->height, in, true, r_shadow_bumpscale_basetexture.value);
texture_mode = GL_LINEAR;
tex->gl_texturenumbumpmap = R_LoadTexture8Bump (va("%s_bump", wal->name), tex->width, tex->height, in, true, r_shadow_bumpscale_basetexture.value);
}
else
#endif
@ -1259,7 +1258,7 @@ qboolean CMod_LoadTexInfo (lump_t *l) //yes I know these load from the same plac
loadmodel->texinfo = out;
loadmodel->numtexinfo = count;
#if !defined(SERVERONLY) && defined(RGLQUAKE)
#if !defined(SERVERONLY) && (defined(RGLQUAKE) || defined(D3DQUAKE))
skytexturenum = -1;
#endif
@ -1462,7 +1461,7 @@ qboolean CMod_LoadFaces (lump_t *l)
if (i == -1)
out->samples = NULL;
#ifdef RGLQUAKE
else if (qrenderer == QR_OPENGL)
else if (qrenderer == QR_OPENGL || qrenderer == QR_DIRECT3D)
out->samples = loadmodel->lightdata + i;
#endif
#ifdef SWQUAKE
@ -2099,7 +2098,7 @@ qboolean CModQ3_LoadShaders (lump_t *l, qboolean useshaders)
numtexinfo = count;
out = map_surfaces = Hunk_Alloc(count*sizeof(*out));
#if !defined(SERVERONLY) && defined(RGLQUAKE)
#if !defined(SERVERONLY) && (defined(RGLQUAKE) || defined(D3DQUAKE))
skytexturenum = -1;
#endif
@ -2111,8 +2110,8 @@ qboolean CModQ3_LoadShaders (lump_t *l, qboolean useshaders)
{
loadmodel->texinfo[i].texture = Hunk_Alloc(sizeof(texture_t));
Q_strncpyz(loadmodel->texinfo[i].texture->name, in->shadername, sizeof(loadmodel->texinfo[i].texture->name));
#ifdef RGLQUAKE
if (qrenderer == QR_OPENGL && !useshaders)
#if defined(RGLQUAKE) || defined(D3DQUAKE)
if ((qrenderer == QR_OPENGL || qrenderer == QR_DIRECT3D) && !useshaders)
{
loadmodel->texinfo[i].texture->gl_texturenum = Mod_LoadHiResTexture(in->shadername, loadname, true, false, true);
if (!loadmodel->texinfo[i].texture->gl_texturenum)
@ -2252,7 +2251,8 @@ qboolean CModRBSP_LoadVertexes (lump_t *l)
qboolean CModQ3_LoadIndexes (lump_t *l)
{
int i, count;
int *in, *out;
int *in;
index_t *out;
in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
@ -3475,7 +3475,7 @@ int CM_GetQ2Palette (void)
BZ_Free(f);
#ifdef RGLQUAKE
#if defined(RGLQUAKE) || defined(D3DQUAKE)
{
extern float vid_gamma;
float f, inf;
@ -3855,7 +3855,7 @@ q2cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned
#ifdef Q3SHADERS
{
extern cvar_t gl_shadeq3;
useshaders = gl_shadeq3.value;
useshaders = qrenderer == QR_OPENGL && gl_shadeq3.value;
}
#else
useshaders = false;
@ -3901,6 +3901,9 @@ q2cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned
{
#if defined(RGLQUAKE)
case QR_OPENGL:
#endif
#if defined(D3DQUAKE)
case QR_DIRECT3D:
#endif
case QR_NONE: //dedicated only
mapisq3 = true;
@ -3922,8 +3925,8 @@ q2cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned
noerrors = noerrors && CModRBSP_LoadFaces (&header.lumps[Q3LUMP_SURFACES]);
else
noerrors = noerrors && CModQ3_LoadFaces (&header.lumps[Q3LUMP_SURFACES]);
#if defined(RGLQUAKE)
if (qrenderer == QR_OPENGL)
#if defined(RGLQUAKE) || defined(D3DQUAKE)
if (qrenderer != QR_NONE)
{
if (noerrors)
GLMod_LoadLighting (&header.lumps[Q3LUMP_LIGHTMAPS]); //fixme: duplicated loading.
@ -3972,7 +3975,7 @@ q2cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned
loadmodel->funcs.LeafPVS = CM_LeafnumPVS;
loadmodel->funcs.LeafnumForPoint = CM_PointLeafnum;
#if defined(RGLQUAKE)
#if defined(RGLQUAKE) || defined(D3DQUAKE)
loadmodel->funcs.LightPointValues = GLQ3_LightGrid;
loadmodel->funcs.StainNode = GLR_Q2BSP_StainNode;
loadmodel->funcs.MarkLights = Q2BSP_MarkLights;
@ -4180,6 +4183,8 @@ q2cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned
break;
#endif
default:
Hunk_FreeToLowMark(start);
return NULL;
Sys_Error("Bad internal renderer on q2 map load\n");
}
}

View file

@ -832,7 +832,7 @@ void Matrix4_Transform3(float *matrix, float *vector, float *product)
product[2] = matrix[2]*vector[0] + matrix[6]*vector[1] + matrix[10]*vector[2] + matrix[14];
}
void ML_ModelViewMatrix(float *modelview, vec3_t viewangles, vec3_t vieworg)
void Matrix4_ModelViewMatrix(float *modelview, vec3_t viewangles, vec3_t vieworg)
{
float tempmat[16];
//load identity.
@ -861,7 +861,7 @@ void ML_ModelViewMatrix(float *modelview, vec3_t viewangles, vec3_t vieworg)
Matrix4_Multiply(tempmat, Matrix4_NewTranslation(-vieworg[0], -vieworg[1], -vieworg[2]), modelview); // put Z going up
}
void ML_ModelViewMatrixFromAxis(float *modelview, vec3_t pn, vec3_t right, vec3_t up, vec3_t vieworg)
void Matrix4_ModelViewMatrixFromAxis(float *modelview, vec3_t pn, vec3_t right, vec3_t up, vec3_t vieworg)
{
float tempmat[16];
@ -886,64 +886,108 @@ void ML_ModelViewMatrixFromAxis(float *modelview, vec3_t pn, vec3_t right, vec3_
}
void ML_ProjectionMatrix(float *proj, float wdivh, float fovy)
void Matrix4_ModelMatrixFromAxis(float *modelview, vec3_t pn, vec3_t right, vec3_t up, vec3_t vieworg)
{
float tempmat[16];
tempmat[ 0] = pn[0];
tempmat[ 1] = pn[1];
tempmat[ 2] = pn[2];
tempmat[ 3] = 0;
tempmat[ 4] = right[0];
tempmat[ 5] = right[1];
tempmat[ 6] = right[2];
tempmat[ 7] = 0;
tempmat[ 8] = up[0];
tempmat[ 9] = up[1];
tempmat[10] = up[2];
tempmat[11] = 0;
tempmat[12] = 0;
tempmat[13] = 0;
tempmat[14] = 0;
tempmat[15] = 1;
Matrix4_Multiply(Matrix4_NewTranslation(vieworg[0], vieworg[1], vieworg[2]), tempmat, modelview); // put Z going up
}
void Matrix4_Identity(float *outm)
{
outm[ 0] = 1;
outm[ 1] = 0;
outm[ 2] = 0;
outm[ 3] = 0;
outm[ 4] = 0;
outm[ 5] = 1;
outm[ 6] = 0;
outm[ 7] = 0;
outm[ 8] = 0;
outm[ 9] = 0;
outm[10] = 1;
outm[11] = 0;
outm[12] = 0;
outm[13] = 0;
outm[14] = 0;
outm[15] = 1;
}
void Matrix4_Projection(float *proj, float wdivh, float fovy, float neard)
{
float xmin, xmax, ymin, ymax;
float nudge = 1;
//proj
ymax = 4 * tan( fovy * M_PI / 360.0 );
ymax = neard * tan( fovy * M_PI / 360.0 );
ymin = -ymax;
xmin = ymin * wdivh;
xmax = ymax * wdivh;
proj[0] = (2*4) / (xmax - xmin);
proj[0] = (2*neard) / (xmax - xmin);
proj[4] = 0;
proj[8] = (xmax + xmin) / (xmax - xmin);
proj[12] = 0;
proj[1] = 0;
proj[5] = (2*4) / (ymax - ymin);
proj[5] = (2*neard) / (ymax - ymin);
proj[9] = (ymax + ymin) / (ymax - ymin);
proj[13] = 0;
proj[2] = 0;
proj[6] = 0;
proj[10] = -1 * nudge;
proj[14] = -2*4 * nudge;
proj[14] = -2*neard * nudge;
proj[3] = 0;
proj[7] = 0;
proj[11] = -1;
proj[15] = 0;
}
void ML_ProjectionMatrix2(float *proj, float fovx, float fovy)
void Matrix4_Projection2(float *proj, float fovx, float fovy, float neard)
{
float xmin, xmax, ymin, ymax;
float nudge = 1;
//proj
ymax = 4 * tan( fovy * M_PI / 360.0 );
ymax = neard * tan( fovy * M_PI / 360.0 );
ymin = -ymax;
xmax = 4 * tan( fovx * M_PI / 360.0 );
xmax = neard * tan( fovx * M_PI / 360.0 );
xmin = -xmax;
proj[0] = (2*4) / (xmax - xmin);
proj[0] = (2*neard) / (xmax - xmin);
proj[4] = 0;
proj[8] = (xmax + xmin) / (xmax - xmin);
proj[12] = 0;
proj[1] = 0;
proj[5] = (2*4) / (ymax - ymin);
proj[5] = (2*neard) / (ymax - ymin);
proj[9] = (ymax + ymin) / (ymax - ymin);
proj[13] = 0;
proj[2] = 0;
proj[6] = 0;
proj[10] = -1 * nudge;
proj[14] = -2*4 * nudge;
proj[14] = -2*neard * nudge;
proj[3] = 0;
proj[7] = 0;
@ -951,7 +995,31 @@ void ML_ProjectionMatrix2(float *proj, float fovx, float fovy)
proj[15] = 0;
}
void Matrix4x4_Invert_Simple (matrix4x4_t *out, const matrix4x4_t *in1)
void Matrix4_Orthographic(float *proj, float xmin, float xmax, float ymax, float ymin,
float znear, float zfar)
{
proj[0] = 2/(xmax-xmin);
proj[4] = 0;
proj[8] = 0;
proj[12] = (xmax+xmin)/(xmax-xmin);
proj[1] = 0;
proj[5] = 2/(ymax-ymin);
proj[9] = 0;
proj[13] = (ymax+ymin)/(ymax-ymin);
proj[2] = 0;
proj[6] = 0;
proj[10] = -2/(zfar-znear);
proj[14] = (zfar+znear)/(zfar-znear);
proj[3] = 0;
proj[7] = 0;
proj[11] = 0;
proj[15] = 1;
}
void Matrix4_Invert_Simple (matrix4x4_t *out, const matrix4x4_t *in1)
{
// we only support uniform scaling, so assume the first row is enough
// (note the lack of sqrt here, because we're trying to undo the scaling,
@ -993,17 +1061,17 @@ void Matrix4x4_Invert_Simple (matrix4x4_t *out, const matrix4x4_t *in1)
//screen->3d
void ML_UnProject(vec3_t in, vec3_t out, vec3_t viewangles, vec3_t vieworg, float wdivh, float fovy)
void Matrix4_UnProject(vec3_t in, vec3_t out, vec3_t viewangles, vec3_t vieworg, float wdivh, float fovy)
{
float modelview[16];
float proj[16];
float tempm[16];
ML_ModelViewMatrix(modelview, viewangles, vieworg);
ML_ProjectionMatrix(proj, wdivh, fovy);
Matrix4_ModelViewMatrix(modelview, viewangles, vieworg);
Matrix4_Projection(proj, wdivh, fovy, 4);
Matrix4_Multiply(proj, modelview, tempm);
Matrix4x4_Invert_Simple((void*)proj, (void*)tempm);
Matrix4_Invert_Simple((void*)proj, (void*)tempm);
{
float v[4], tempv[4];
@ -1023,13 +1091,13 @@ void ML_UnProject(vec3_t in, vec3_t out, vec3_t viewangles, vec3_t vieworg, floa
//returns fractions of screen.
//uses GL style rotations and translations and stuff.
//3d -> screen (fixme: offscreen return values needed)
void ML_Project (vec3_t in, vec3_t out, vec3_t viewangles, vec3_t vieworg, float wdivh, float fovy)
void Matrix4_Project (vec3_t in, vec3_t out, vec3_t viewangles, vec3_t vieworg, float wdivh, float fovy)
{
float modelview[16];
float proj[16];
ML_ModelViewMatrix(modelview, viewangles, vieworg);
ML_ProjectionMatrix(proj, wdivh, fovy);
Matrix4_ModelViewMatrix(modelview, viewangles, vieworg);
Matrix4_Projection(proj, wdivh, fovy, 4);
{
float v[4], tempv[4];
@ -1120,3 +1188,4 @@ void MakeNormalVectors (vec3_t forward, vec3_t right, vec3_t up)
VectorNormalize (right);
CrossProduct (right, forward, up);
}

View file

@ -114,14 +114,19 @@ typedef struct {
} matrix4x4_t;
//used for crosshair stuff.
void ML_Project (vec3_t in, vec3_t out, vec3_t viewangles, vec3_t vieworg, float wdivh, float fovy);
void Matrix4_Project (vec3_t in, vec3_t out, vec3_t viewangles, vec3_t vieworg, float wdivh, float fovy);
void Matrix4_UnProject(vec3_t in, vec3_t out, vec3_t viewangles, vec3_t vieworg, float wdivh, float fovy);
void Matrix3_Multiply (vec3_t *in1, vec3_t *in2, vec3_t *out);
void Matrix4_Multiply(float *a, float *b, float *out);
void Matrix4_Transform3(float *matrix, float *vector, float *product);
void Matrix4_Transform4(float *matrix, float *vector, float *product);
void Matrix4x4_Invert_Simple (matrix4x4_t *out, const matrix4x4_t *in1);
void ML_ModelViewMatrix(float *modelview, vec3_t viewangles, vec3_t vieworg);
void ML_ProjectionMatrix2(float *proj, float fovx, float fovy);
void ML_ModelViewMatrixFromAxis(float *modelview, vec3_t pn, vec3_t right, vec3_t up, vec3_t vieworg);
void Matrix4_Invert_Simple (matrix4x4_t *out, const matrix4x4_t *in1);
void Matrix4_ModelViewMatrix(float *modelview, vec3_t viewangles, vec3_t vieworg);
void Matrix4_Projection2(float *proj, float fovx, float fovy, float neard);
void Matrix4_Orthographic(float *proj, float xmin, float xmax, float ymax, float ymin, float znear, float zfar);
void Matrix4_ModelViewMatrixFromAxis(float *modelview, vec3_t pn, vec3_t right, vec3_t up, vec3_t vieworg);
void AddPointToBounds (vec3_t v, vec3_t mins, vec3_t maxs);
qboolean BoundsIntersect (vec3_t mins1, vec3_t maxs1, vec3_t mins2, vec3_t maxs2);
void ClearBounds (vec3_t mins, vec3_t maxs);

View file

@ -533,7 +533,7 @@ dblbreak:
if (strlen(s) >= sizeof(copy)-1)
return false;
strcpy (copy, s);
// strip off a trailing :port if present
for (colon = copy ; *colon ; colon++)

View file

@ -126,6 +126,128 @@ typedef struct beamseg_s
float texture_s;
} beamseg_t;
typedef struct skytris_s {
struct skytris_s *next;
vec3_t org;
vec3_t x;
vec3_t y;
float area;
float nexttime;
struct msurface_s *face;
} skytris_t;
//these could be deltas or absolutes depending on ramping mode.
typedef struct {
vec3_t rgb;
float alpha;
float scale;
float rotation;
} ramp_t;
typedef enum { BM_BLEND, BM_BLENDCOLOUR, BM_ADD, BM_SUBTRACT } blendmode_t;
// TODO: merge in alpha with rgb to gain benefit of vector opts
typedef struct part_type_s {
char name[MAX_QPATH];
char texname[MAX_QPATH];
vec3_t rgb;
vec3_t rgbchange;
vec3_t rgbrand;
int colorindex;
int colorrand;
float rgbchangetime;
vec3_t rgbrandsync;
float scale, alpha;
float alphachange;
float die, randdie;
float randomvel, veladd;
float orgadd;
float offsetspread;
float offsetspreadvert;
float randomvelvert;
float randscale;
float spawntime;
float spawnchance;
enum {PT_NORMAL, PT_SPARK, PT_SPARKFAN, PT_TEXTUREDSPARK, PT_BEAM, PT_DECAL} type;
blendmode_t blendmode;
float rotationstartmin, rotationstartrand;
float rotationmin, rotationrand;
float scaledelta;
float count;
float countrand;
int texturenum;
#ifdef D3DQUAKE
void *d3dtexture;
#endif
int assoc;
int cliptype;
int inwater;
float clipcount;
int emit;
float emittime;
float emitrand;
float emitstart;
float areaspread;
float areaspreadvert;
float scalefactor;
float invscalefactor;
float spawnparam1;
float spawnparam2;
/* float spawnparam3; */
float offsetup; // make this into a vec3_t later with dir, possibly for mdls
enum {
SM_BOX, //box = even spread within the area
SM_CIRCLE, //circle = around edge of a circle
SM_BALL, //ball = filled sphere
SM_SPIRAL, //spiral = spiral trail
SM_TRACER, //tracer = tracer trail
SM_TELEBOX, //telebox = q1-style telebox
SM_LAVASPLASH, //lavasplash = q1-style lavasplash
SM_UNICIRCLE, //unicircle = uniform circle
SM_FIELD, //field = synced field (brightfield, etc)
SM_DISTBALL // uneven distributed ball
} spawnmode;
float gravity;
vec3_t friction;
float clipbounce;
int stains;
enum {RAMP_NONE, RAMP_DELTA, RAMP_ABSOLUTE} rampmode;
int rampindexes;
ramp_t *ramp;
int loaded;
particle_t *particles;
clippeddecal_t *clippeddecals;
beamseg_t *beams;
skytris_t *skytris;
struct part_type_s *nexttorun;
unsigned int flags;
#define PT_VELOCITY 0x001
#define PT_FRICTION 0x002
#define PT_CHANGESCOLOUR 0x004
#define PT_CITRACER 0x008 // Q1-style tracer behavior for colorindex
#define PT_INVFRAMETIME 0x010 // apply inverse frametime to count (causes emits to be per frame)
#define PT_AVERAGETRAIL 0x020 // average trail points from start to end, useful with t_lightning, etc
#define PT_NOSTATE 0x040 // don't use trailstate for this emitter (careful with assoc...)
#define PT_NOSPREADFIRST 0x080 // don't randomize org/vel for first generated particle
#define PT_NOSPREADLAST 0x100 // don't randomize org/vel for last generated particle
unsigned int state;
#define PS_INRUNLIST 0x1 // particle type is currently in execution list
} part_type_t;
#define PARTICLE_Z_CLIP 8.0
#define frandom() (rand()*(1.0f/RAND_MAX))
@ -179,8 +301,6 @@ void P_EmitSkyEffectTris(struct model_s *mod, struct msurface_s *fa);
// trailstate functions
void P_DelinkTrailstate(trailstate_t **tsk);
typedef enum { BM_BLEND, BM_BLENDCOLOUR, BM_ADD, BM_SUBTRACT } blendmode_t;
// used for callback
extern cvar_t r_particlesdesc;

811
engine/d3d/d3d_draw.c Normal file
View file

@ -0,0 +1,811 @@
#include "quakedef.h"
#ifdef D3DQUAKE
#include "d3dquake.h"
#define MAX_WIDTH 512
#define MAX_HEIGHT 512
void *d3dexplosiontexture;
void *d3dballtexture;
LPDIRECTDRAWSURFACE7 draw_chars_tex;
mpic_t *conback_tex;
typedef struct d3dcachepic_s
{
char name[MAX_QPATH];
mpic_t pic;
} d3dcachepic_t;
#define MAX_CACHED_PICS 512 //a temporary solution
d3dcachepic_t d3dmenu_cachepics[MAX_CACHED_PICS];
int d3dmenu_numcachepics;
typedef struct {
float x, y, z;
int colour;
float s, t;
} d3dquadvert_t;
d3dquadvert_t d3dquadvert[4];
index_t d3dquadindexes[6] = {
0, 1, 2,
0, 2, 3
};
//pD3DDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX2, d3dstate.vertbuf, d3dstate.numverts, d3dstate.indexbuf, d3dstate.numindicies, 0);
static void Upload_Texture_32(LPDIRECTDRAWSURFACE7 surf, unsigned int *data, int width, int height)
{
int x, y;
unsigned int *dest;
unsigned char swapbuf[4];
unsigned char swapbuf2[4];
DDSURFACEDESC2 desc;
memset(&desc, 0, sizeof(desc));
surf->lpVtbl->Lock(surf, NULL, &desc, DDLOCK_NOSYSLOCK|DDLOCK_WAIT|DDLOCK_WRITEONLY|DDLOCK_DISCARDCONTENTS, NULL);
if (width == desc.dwWidth && height == desc.dwHeight)
{
// if (desc.lPitch == twidth*4)
// {
// memcpy(desc.lpSurface, data, width*height*4);
// }
// else
{
for (y = 0; y < desc.dwHeight; y++)
{
dest = (unsigned int *)((char *)desc.lpSurface + desc.lPitch*y);
for (x = 0; x < desc.dwWidth; x++)
{
*(unsigned int*)swapbuf2 = *(unsigned int*)swapbuf = data[x];
swapbuf[0] = swapbuf2[2];
swapbuf[2] = swapbuf2[0];
dest[x] = *(unsigned int*)swapbuf;
}
data += width;
}
}
}
else
{
int x, y;
int iny;
unsigned int *scaled, *row, *inrow;
for (y = 0; y < desc.dwHeight; y++)
{
row = (unsigned int*)((char *)desc.lpSurface + desc.lPitch*y);
iny = (y * height) / desc.dwHeight;
inrow = data + width*iny;
for (x = 0; x < desc.dwWidth; x++)
{
*(unsigned int*)swapbuf2 = *(unsigned int*)swapbuf = inrow[(x * width)/desc.dwWidth];
swapbuf[0] = swapbuf2[2];
swapbuf[2] = swapbuf2[0];
row[x] = *(unsigned int*)swapbuf;
}
}
//mimic opengl and draw it white
// memset(desc.lpSurface, 255, twidth*theight*4);
}
surf->lpVtbl->Unlock(surf, NULL);
}
void D3D_MipMap (qbyte *out, qbyte *in, int width, int height)
{
int i, j;
width <<=2;
height >>= 1;
for (i=0 ; i<height ; i++, in+=width)
{
for (j=0 ; j<width ; j+=8, out+=4, in+=8)
{
out[0] = (in[0] + in[4] + in[width+0] + in[width+4])>>2;
out[1] = (in[1] + in[5] + in[width+1] + in[width+5])>>2;
out[2] = (in[2] + in[6] + in[width+2] + in[width+6])>>2;
out[3] = (in[3] + in[7] + in[width+3] + in[width+7])>>2;
}
}
}
//create a basic shader from a 32bit image
void *D3D_LoadTexture_32(char *name, unsigned int *data, int width, int height, int flags)
{
int x, y;
unsigned int *dest;
unsigned char swapbuf[4];
unsigned char swapbuf2[4];
static unsigned char mipdata[(MAX_WIDTH/2)*(MAX_HEIGHT/2)][4];
DWORD tflags;
DWORD twidth = width;
DWORD theight = height;
D3DX_SURFACEFORMAT tformat = D3DX_SF_A8R8G8B8;
LPDIRECTDRAWSURFACE7 newsurf;
DWORD nummips;
/* if (!(flags & TF_MANDATORY))
{
Con_Printf("Texture upload missing flags\n");
return NULL;
}
*/
if (flags & TF_MIPMAP)
tflags = 0;
else
tflags = D3DX_TEXTURE_NOMIPMAP;
D3DXCreateTexture(pD3DDev, &tflags, &twidth, &theight, &tformat, NULL, &newsurf, &nummips);
if (!newsurf)
return NULL;
if (tformat != D3DX_SF_A8R8G8B8)
Sys_Error("Couldn't create a d3d texture with a usable texture format");
Upload_Texture_32(newsurf, data, width, height);
if (flags & TF_MIPMAP)
{
LPDIRECTDRAWSURFACE7 miptex;
LPDIRECTDRAWSURFACE7 lasttex;
DDSCAPS2 caps;
memset(&caps, 0, sizeof(caps));
caps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
newsurf->lpVtbl->GetAttachedSurface(newsurf, &caps, &miptex);
while (miptex)
{
D3D_MipMap(mipdata, data, width, height);
data = mipdata;
width/=2;
height/=2;
Upload_Texture_32(miptex, mipdata, width, height);
lasttex = miptex;
miptex->lpVtbl->GetAttachedSurface(miptex, &caps, &miptex);
lasttex->lpVtbl->Release(lasttex);
}
}
return newsurf;
}
//create a basic shader from an 8bit image with 24bit palette
void *D3D_LoadTexture_8_Pal24(char *name, unsigned char *data, int width, int height, int flags, unsigned char *palette, int transparentpix)
{
//just expands it to 32bpp and passes it on
static unsigned char out[MAX_WIDTH*MAX_HEIGHT][4];
int i;
if (!(flags & TF_ALPHA))
transparentpix = 256;
if (width*height > MAX_WIDTH*MAX_HEIGHT)
Sys_Error("GL_Upload8_Pal24: too big");
for (i = width*height; i >= 0 ; i--)
{
out[i][0] = palette[data[i]*3+0];
out[i][1] = palette[data[i]*3+1];
out[i][2] = palette[data[i]*3+2];
out[i][3] = 255*(data[i] != transparentpix);
}
return D3D_LoadTexture_32(name, (unsigned int*)out, width, height, flags);
}
void *D3D_LoadTexture_8_Pal32(char *name, unsigned char *data, int width, int height, int flags, unsigned char *palette)
{
//just expands it to 32bpp and passes it on
static unsigned char out[MAX_WIDTH*MAX_HEIGHT][4];
int i;
if (width*height > MAX_WIDTH*MAX_HEIGHT)
Sys_Error("GL_Upload8_Pal24: too big");
for (i = width*height; i >= 0 ; i--)
{
out[i][0] = palette[data[i]*4+0];
out[i][1] = palette[data[i]*4+1];
out[i][2] = palette[data[i]*4+2];
out[i][3] = palette[data[i]*4+3];
}
return D3D_LoadTexture_32(name, (unsigned int*)out, width, height, flags);
}
void D3D_UnloadTexture(LPDIRECTDRAWSURFACE7 tex)
{
tex->lpVtbl->Release(tex);
}
static qbyte exptexture[16][16] =
{
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0},
{0,0,0,1,1,1,1,1,3,1,1,2,1,0,0,0},
{0,0,0,1,1,1,1,4,4,4,5,4,2,1,1,0},
{0,0,1,1,6,5,5,8,6,8,3,6,3,2,1,0},
{0,0,1,5,6,7,5,6,8,8,8,3,3,1,0,0},
{0,0,0,1,6,8,9,9,9,9,4,6,3,1,0,0},
{0,0,2,1,7,7,9,9,9,9,5,3,1,0,0,0},
{0,0,2,4,6,8,9,9,9,9,8,6,1,0,0,0},
{0,0,2,2,3,5,6,8,9,8,8,4,4,1,0,0},
{0,0,1,2,4,1,8,7,8,8,6,5,4,1,0,0},
{0,1,1,1,7,8,1,6,7,5,4,7,1,0,0,0},
{0,1,2,1,1,5,1,3,4,3,1,1,0,0,0,0},
{0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
};
void D3D_InitParticleTexture (void)
{
#define PARTICLETEXTURESIZE 64
int x,y;
float dx, dy, d;
qbyte data[PARTICLETEXTURESIZE*PARTICLETEXTURESIZE][4];
//Explosion texture
for (x=0 ; x<16 ; x++)
{
for (y=0 ; y<16 ; y++)
{
data[y*16+x][0] = 255;
data[y*16+x][1] = 255;
data[y*16+x][2] = 255;
data[y*16+x][3] = exptexture[x][y]*255/9.0;
}
}
d3dexplosiontexture = D3D_LoadTexture_32("", (unsigned int*)data, 16, 16, TF_ALPHA|TF_NOTBUMPMAP|TF_NOMIPMAP);
memset(data, 255, sizeof(data));
for (y = 0;y < PARTICLETEXTURESIZE;y++)
{
dy = (y - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f-1);
for (x = 0;x < PARTICLETEXTURESIZE;x++)
{
dx = (x - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f-1);
d = 256 * (1 - (dx*dx+dy*dy));
d = bound(0, d, 255);
data[y*PARTICLETEXTURESIZE+x][3] = (qbyte) d;
}
}
d3dballtexture = D3D_LoadTexture_32("", (unsigned int*)data, PARTICLETEXTURESIZE, PARTICLETEXTURESIZE, TF_ALPHA|TF_NOTBUMPMAP|TF_NOMIPMAP);
}
mpic_t *(D3D_Draw_SafePicFromWad) (char *name)
{
LPDIRECTDRAWSURFACE7 *p;
d3dcachepic_t *pic;
qpic_t *qpic;
int i;
for (i = 0; i < d3dmenu_numcachepics; i++)
{
if (!strcmp(d3dmenu_cachepics[i].name, name))
return &d3dmenu_cachepics[i].pic;
}
qpic = (qpic_t *)W_SafeGetLumpName (name);
if (!qpic)
{
return NULL;
}
SwapPic (qpic);
pic = &d3dmenu_cachepics[d3dmenu_numcachepics++];
Q_strncpyz (pic->name, name, sizeof(pic->name));
pic->pic.width = qpic->width;
pic->pic.height = qpic->height;
p = (LPDIRECTDRAWSURFACE7*)&pic->pic.data;
if (!strcmp(name, "conchars"))
*p = draw_chars_tex;
else
{
*p = Mod_LoadReplacementTexture(pic->name, "wad", false, true, true);
if (!*p)
*p = D3D_LoadTexture_8_Pal24(name, (unsigned char*)(qpic+1), qpic->width, qpic->height, TF_NOMIPMAP|TF_ALPHA|TF_NOTBUMPMAP, host_basepal, 255);
}
// Con_Printf("Fixme: D3D_Draw_SafePicFromWad\n");
return &pic->pic;
}
mpic_t *(D3D_Draw_SafeCachePic) (char *path)
{
LPDIRECTDRAWSURFACE7 *p;
d3dcachepic_t *pic;
qpic_t *qpic;
int i;
for (i = 0; i < d3dmenu_numcachepics; i++)
{
if (!strcmp(d3dmenu_cachepics[i].name, path))
return &d3dmenu_cachepics[i].pic;
}
qpic = (qpic_t *)COM_LoadTempFile (path);
if (!qpic)
{
return NULL;
}
SwapPic (qpic);
pic = &d3dmenu_cachepics[d3dmenu_numcachepics++];
Q_strncpyz (pic->name, path, sizeof(pic->name));
pic->pic.width = qpic->width;
pic->pic.height = qpic->height;
p = (LPDIRECTDRAWSURFACE7*)&pic->pic.data;
*p = Mod_LoadReplacementTexture(pic->name, "gfx", false, true, true);
if (!*p)
*p = D3D_LoadTexture_8_Pal24(path, (unsigned char*)(qpic+1), qpic->width, qpic->height, TF_NOMIPMAP|TF_ALPHA|TF_NOTBUMPMAP, host_basepal, 255);
// Con_Printf("Fixme: D3D_Draw_SafeCachePic\n");
return &pic->pic;
}
mpic_t *(D3D_Draw_CachePic) (char *path)
{
mpic_t *pic;
pic = D3D_Draw_SafeCachePic(path);
if (!pic)
Sys_Error("Couldn't load picture %s", path);
return pic;
}
void (D3D_Draw_ReInit) (void)
{
d3dmenu_numcachepics = 0;
draw_chars = W_SafeGetLumpName ("conchars");
draw_chars_tex = Mod_LoadReplacementTexture("conchars", "gfx", false, true, true);
if (!draw_chars_tex)
draw_chars_tex = D3D_LoadTexture_8_Pal24("conchars", draw_chars, 128, 128, TF_NOMIPMAP|TF_ALPHA|TF_NOTBUMPMAP, host_basepal, 0);
//now emit the conchars picture as if from a wad.
strcpy(d3dmenu_cachepics[d3dmenu_numcachepics].name, "conchars");
d3dmenu_cachepics[d3dmenu_numcachepics].pic.width = 128;
d3dmenu_cachepics[d3dmenu_numcachepics].pic.height = 128;
*(int *)&d3dmenu_cachepics[d3dmenu_numcachepics].pic.data = draw_chars_tex;
d3dmenu_numcachepics++;
conback_tex = D3D_Draw_SafeCachePic("gfx/conback.lmp");
Plug_DrawReloadImages();
D3D_InitParticleTexture();
}
void (D3D_Draw_Init) (void)
{
D3D_Draw_ReInit();
}
void (D3D_Draw_Character) (int x, int y, unsigned int num)
{
int row;
int col;
float frow, fcol, size;
#define char_instep 0
num &= 255;
if (num == ' ')
return;
row = num>>4;
col = num&15;
frow = row*0.0625+char_instep;
fcol = col*0.0625+char_instep;
size = 0.0625-char_instep*2;
d3dquadvert[0].x = x;
d3dquadvert[0].y = y;
d3dquadvert[0].z = 0;
d3dquadvert[0].colour = 0xffffffff;
d3dquadvert[0].s = fcol;
d3dquadvert[0].t = frow;
d3dquadvert[1].x = x+8;
d3dquadvert[1].y = y;
d3dquadvert[1].z = 0;
d3dquadvert[1].colour = 0xffffffff;
d3dquadvert[1].s = fcol+size;
d3dquadvert[1].t = frow;
d3dquadvert[2].x = x+8;
d3dquadvert[2].y = y+8;
d3dquadvert[2].z = 0;
d3dquadvert[2].colour = 0xffffffff;
d3dquadvert[2].s = fcol+size;
d3dquadvert[2].t = frow+size;
d3dquadvert[3].x = x;
d3dquadvert[3].y = y+8;
d3dquadvert[3].z = 0;
d3dquadvert[3].colour = 0xffffffff;
d3dquadvert[3].s = fcol;
d3dquadvert[3].t = frow+size;
pD3DDev->lpVtbl->SetTexture(pD3DDev, 0, draw_chars_tex);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_TEXCOORDINDEX, 0);
pD3DDev->lpVtbl->DrawIndexedPrimitive(pD3DDev, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1, d3dquadvert, 4, d3dquadindexes, 6, 0);
}
void (D3D_Draw_ColouredCharacter) (int x, int y, unsigned int num)
{
int row;
int col;
float frow, fcol, size;
unsigned int imgcolour;
unsigned char *c = (unsigned char *)&imgcolour;
#define char_instep 0
if (num&0xffff == ' ')
return;
col = (num & CON_FGMASK) >> CON_FGSHIFT;
c[0] = consolecolours[col].fb*255;
c[1] = consolecolours[col].fg*255;
c[2] = consolecolours[col].fr*255;
c[3] = (num & CON_HALFALPHA)?128:255;
num &= 0xff;
row = num>>4;
col = num&15;
frow = row*0.0625+char_instep;
fcol = col*0.0625+char_instep;
size = 0.0625-char_instep*2;
d3dquadvert[0].x = x;
d3dquadvert[0].y = y;
d3dquadvert[0].z = 0;
d3dquadvert[0].colour = imgcolour;
d3dquadvert[0].s = fcol;
d3dquadvert[0].t = frow;
d3dquadvert[1].x = x+8;
d3dquadvert[1].y = y;
d3dquadvert[1].z = 0;
d3dquadvert[1].colour = imgcolour;
d3dquadvert[1].s = fcol+size;
d3dquadvert[1].t = frow;
d3dquadvert[2].x = x+8;
d3dquadvert[2].y = y+8;
d3dquadvert[2].z = 0;
d3dquadvert[2].colour = imgcolour;
d3dquadvert[2].s = fcol+size;
d3dquadvert[2].t = frow+size;
d3dquadvert[3].x = x;
d3dquadvert[3].y = y+8;
d3dquadvert[3].z = 0;
d3dquadvert[3].colour = imgcolour;
d3dquadvert[3].s = fcol;
d3dquadvert[3].t = frow+size;
pD3DDev->lpVtbl->SetTexture(pD3DDev, 0, draw_chars_tex);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_TEXCOORDINDEX, 0);
pD3DDev->lpVtbl->DrawIndexedPrimitive(pD3DDev, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1, d3dquadvert, 4, d3dquadindexes, 6, 0);
}
void (D3D_Draw_String) (int x, int y, const qbyte *str)
{
while(*str)
{
D3D_Draw_Character(x, y, *str++);
x+=8;
}
}
void (D3D_Draw_Alt_String) (int x, int y, const qbyte *str)
{
while(*str)
{
D3D_Draw_Character(x, y, *str++ | 128);
x+=8;
}
}
void (D3D_Draw_Crosshair) (void)
{
D3D_Draw_Character(vid.width/2 - 4, vid.height/2 - 4, '+');
}
void (D3D_Draw_DebugChar) (qbyte num)
{
Sys_Error("D3D function not implemented\n");
}
void (D3D_Draw_TransPicTranslate) (int x, int y, int w, int h, qbyte *pic, qbyte *translation)
{
// Sys_Error("D3D function not implemented\n");
}
void (D3D_Draw_TileClear) (int x, int y, int w, int h)
{
// Sys_Error("D3D function not implemented\n");
}
void (D3D_Draw_Fill_I) (int x, int y, int w, int h, unsigned int imgcolour)
{
d3dquadvert[0].x = x;
d3dquadvert[0].y = y;
d3dquadvert[0].z = 0;
d3dquadvert[0].colour = imgcolour;
d3dquadvert[0].s = 0;
d3dquadvert[0].t = 0;
d3dquadvert[1].x = x+w;
d3dquadvert[1].y = y;
d3dquadvert[1].z = 0;
d3dquadvert[1].colour = imgcolour;
d3dquadvert[1].s = 0;
d3dquadvert[1].t = 0;
d3dquadvert[2].x = x+w;
d3dquadvert[2].y = y+h;
d3dquadvert[2].z = 0;
d3dquadvert[2].colour = imgcolour;
d3dquadvert[2].s = 0;
d3dquadvert[2].t = 0;
d3dquadvert[3].x = x;
d3dquadvert[3].y = y+h;
d3dquadvert[3].z = 0;
d3dquadvert[3].colour = imgcolour;
d3dquadvert[3].s = 0;
d3dquadvert[3].t = 0;
pD3DDev->lpVtbl->SetTexture(pD3DDev, 0, NULL);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHATESTENABLE, FALSE );
pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHABLENDENABLE, TRUE );
pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA);
pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA);
pD3DDev->lpVtbl->DrawIndexedPrimitive(pD3DDev, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1, d3dquadvert, 4, d3dquadindexes, 6, 0);
pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE );
pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHATESTENABLE, TRUE );
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
}
void (D3D_Draw_FillRGB) (int x, int y, int w, int h, float r, float g, float b)
{
char colours[4];
colours[0] = b*255;
colours[1] = g*255;
colours[2] = r*255;
colours[3] = 255;
D3D_Draw_Fill_I(x, y, w, h, *(unsigned int*)colours);
}
void (D3D_Draw_Fill) (int x, int y, int w, int h, int c)
{
D3D_Draw_FillRGB(x, y, w, h, host_basepal[c*3+0]/255.0f, host_basepal[c*3+1]/255.0f, host_basepal[c*3+2]/255.0f);
}
void (D3D_Draw_FadeScreen) (void)
{
// Sys_Error("D3D function not implemented\n");
}
void (D3D_Draw_BeginDisc) (void)
{
// Sys_Error("D3D function not implemented\n");
}
void (D3D_Draw_EndDisc) (void)
{
// Sys_Error("D3D function not implemented\n");
}
static int imgcolour;
void (D3D_Draw_Fill_Colours) (int x, int y, int w, int h)
{
D3D_Draw_Fill_I(x, y, w, h, imgcolour);
}
void (D3D_Draw_Image) (float x, float y, float w, float h, float s1, float t1, float s2, float t2, mpic_t *pic)
{
LPDIRECTDRAWSURFACE7 *p;
if (!conback_tex)
return;
if (!pic)
return;
d3dquadvert[0].x = x;
d3dquadvert[0].y = y;
d3dquadvert[0].z = 0;
d3dquadvert[0].colour = imgcolour;
d3dquadvert[0].s = s1;// - 3.0/pic->width;
d3dquadvert[0].t = t1;
d3dquadvert[1].x = x+w;
d3dquadvert[1].y = y;
d3dquadvert[1].z = 0;
d3dquadvert[1].colour = imgcolour;
d3dquadvert[1].s = s2;// - 3.0/pic->width;
d3dquadvert[1].t = t1;
d3dquadvert[2].x = x+w;
d3dquadvert[2].y = y+h;
d3dquadvert[2].z = 0;
d3dquadvert[2].colour = imgcolour;
d3dquadvert[2].s = s2;// - 3.0/pic->width;
d3dquadvert[2].t = t2;
d3dquadvert[3].x = x;
d3dquadvert[3].y = y+h;
d3dquadvert[3].z = 0;
d3dquadvert[3].colour = imgcolour;
d3dquadvert[3].s = s1;// - 3.0/pic->width;
d3dquadvert[3].t = t2;
p = (LPDIRECTDRAWSURFACE7*)&pic->data;
pD3DDev->lpVtbl->SetTexture(pD3DDev, 0, *p);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_TEXCOORDINDEX, 0);
pD3DDev->lpVtbl->DrawIndexedPrimitive(pD3DDev, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1, d3dquadvert, 4, d3dquadindexes, 6, 0);
}
void (D3D_Draw_ScalePic) (int x, int y, int width, int height, mpic_t *pic)
{
D3D_Draw_Image(x, y, width, height, 0, 0, 1, 1, pic);
}
void (D3D_Draw_SubPic) (int x, int y, mpic_t *pic, int srcx, int srcy, int width, int height)
{
float s, t;
float sw, tw;
if (!pic)
return;
s = (float)srcx/pic->width;
t = (float)srcy/pic->height;
sw = (float)width/pic->width;
tw = (float)height/pic->height;
D3D_Draw_Image(x, y, width, height, s, t, s+sw, t+tw, pic);
}
void (D3D_Draw_TransPic) (int x, int y, mpic_t *pic)
{
if (!pic)
return;
D3D_Draw_Image(x, y, pic->width, pic->height, 0, 0, 1, 1, pic);
}
void (D3D_Draw_Pic) (int x, int y, mpic_t *pic)
{
if (!pic)
return;
D3D_Draw_Image(x, y, pic->width, pic->height, 0, 0, 1, 1, pic);
}
void (D3D_Draw_ImageColours) (float r, float g, float b, float a)
{
unsigned char *c = (unsigned char *)&imgcolour;
c[0] = b*255;
c[1] = g*255;
c[2] = r*255;
c[3] = a*255;
}
void (D3D_Draw_ConsoleBackground) (int lines)
{
D3D_Draw_ImageColours(1,1,1,1);
D3D_Draw_Image(0, 0, vid.width, lines, 0, 1 - (float)lines/vid.height, 1, 1, conback_tex);
}
void (D3D_Draw_EditorBackground) (int lines)
{
D3D_Draw_ConsoleBackground(lines);
}
void (D3D_Media_ShowFrameBGR_24_Flip) (qbyte *framedata, int inwidth, int inheight)
{
mpic_t pic;
LPDIRECTDRAWSURFACE7 *p;
p = (LPDIRECTDRAWSURFACE7*)&pic.data;
*p = D3D_LoadTexture_32("", (unsigned int*)framedata, inwidth, inheight, TF_NOMIPMAP|TF_NOALPHA|TF_NOTBUMPMAP);
D3D_Set2D ();
D3D_Draw_ImageColours(1,1,1,1);
pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHATESTENABLE, FALSE );
D3D_Draw_Image(0, 0, vid.width, vid.height, 0, 1, 1, 0, &pic);
pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHATESTENABLE, TRUE );
D3D_UnloadTexture(*p);
} //input is bottom up...
void (D3D_Media_ShowFrameRGBA_32) (qbyte *framedata, int inwidth, int inheight)
{
mpic_t pic;
LPDIRECTDRAWSURFACE7 *p;
pic.width = inwidth;
pic.height = inheight;
pic.flags = 0;
p = (LPDIRECTDRAWSURFACE7*)&pic.data;
*p = D3D_LoadTexture_32("", (unsigned int*)framedata, inwidth, inheight, TF_NOMIPMAP|TF_NOALPHA|TF_NOTBUMPMAP);
D3D_Set2D ();
D3D_Draw_ImageColours(1,1,1,1);
pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHATESTENABLE, FALSE );
D3D_Draw_Image(0, 0, vid.width, vid.height, 0, 0, 1, 1, &pic);
pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHATESTENABLE, TRUE );
D3D_UnloadTexture(*p);
} //top down
void (D3D_Media_ShowFrame8bit) (qbyte *framedata, int inwidth, int inheight, qbyte *palette)
{
mpic_t pic;
LPDIRECTDRAWSURFACE7 *p;
p = (LPDIRECTDRAWSURFACE7*)&pic.data;
*p = D3D_LoadTexture_8_Pal24("", (unsigned char*)framedata, inwidth, inheight, TF_NOMIPMAP|TF_NOALPHA|TF_NOTBUMPMAP, palette, 256);
D3D_Set2D ();
D3D_Draw_ImageColours(1,1,1,1);
pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHATESTENABLE, FALSE );
D3D_Draw_Image(0, 0, vid.width, vid.height, 0, 1, 1, 0, &pic);
pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHATESTENABLE, TRUE );
D3D_UnloadTexture(*p);
} //paletted topdown (framedata is 8bit indexes into palette)
#endif

696
engine/d3d/d3d_mesh.c Normal file
View file

@ -0,0 +1,696 @@
#include "quakedef.h"
#ifdef D3DQUAKE
#include "d3dquake.h"
#include "com_mesh.h"
extern cvar_t r_fullbrightSkins;
extern cvar_t r_vertexdlights;
typedef struct {
float x, y, z;
float s, t;
} meshvert_t;
typedef struct {
float x, y, z;
unsigned int colour;
float s, t;
} meshcolouredvert_t;
void D3D_DrawMesh(mesh_t *mesh)
{
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG2, D3DTA_CURRENT);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
{
int v;
vec3_t *xyz;
byte_vec4_t *colour;
vec2_t *wm;
xyz = mesh->xyz_array;
wm = mesh->st_array;
colour = mesh->colors_array;
if (colour)
{
meshcolouredvert_t *meshvert = alloca(sizeof(meshcolouredvert_t)*mesh->numvertexes);
for (v = 0; v < mesh->numvertexes; v++, xyz++, wm++, colour++)
{
meshvert[v].x = (*xyz)[0];
meshvert[v].y = (*xyz)[1];
meshvert[v].z = (*xyz)[2];
meshvert[v].colour = *(unsigned int*)colour;
meshvert[v].s = (*wm)[0];
meshvert[v].t = (*wm)[1];
}
pD3DDev->lpVtbl->DrawIndexedPrimitive(pD3DDev, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1, meshvert, mesh->numvertexes, mesh->indexes, mesh->numindexes, 0);
}
else
{
meshvert_t *meshvert = alloca(sizeof(meshvert_t)*mesh->numvertexes);
for (v = 0; v < mesh->numvertexes; v++, xyz++, wm++)
{
meshvert[v].x = (*xyz)[0];
meshvert[v].y = (*xyz)[1];
meshvert[v].z = (*xyz)[2];
meshvert[v].s = (*wm)[0];
meshvert[v].t = (*wm)[1];
}
pD3DDev->lpVtbl->DrawIndexedPrimitive(pD3DDev, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_TEX1, meshvert, mesh->numvertexes, mesh->indexes, mesh->numindexes, 0);
}
}
}
hashtable_t skincolourmapped;
void d3d_GAliasFlushSkinCache(void)
{
int i;
bucket_t *b;
for (i = 0; i < skincolourmapped.numbuckets; i++)
{
while((b = skincolourmapped.bucket[i]))
{
skincolourmapped.bucket[i] = b->next;
BZ_Free(b->data);
}
}
if (skincolourmapped.bucket)
BZ_Free(skincolourmapped.bucket);
skincolourmapped.bucket = NULL;
skincolourmapped.numbuckets = 0;
}
static galiastexnum_t *D3D_ChooseSkin(galiasinfo_t *inf, char *modelname, int surfnum, entity_t *e)
{
galiasskin_t *skins;
galiastexnum_t *texnums;
int frame;
int tc, bc;
int local;
if (!gl_nocolors.value)
{
if (e->scoreboard)
{
if (!e->scoreboard->skin)
Skin_Find(e->scoreboard);
tc = e->scoreboard->topcolor;
bc = e->scoreboard->bottomcolor;
//colour forcing
if (cl.splitclients<2 && !(cl.fpd & FPD_NO_FORCE_COLOR)) //no colour/skin forcing in splitscreen.
{
if (cl.teamplay && cl.spectator)
{
local = Cam_TrackNum(0);
if (local < 0)
local = cl.playernum[0];
}
else
local = cl.playernum[0];
if (cl.teamplay && !strcmp(e->scoreboard->team, cl.players[local].team))
{
if (cl_teamtopcolor>=0)
tc = cl_teamtopcolor;
if (cl_teambottomcolor>=0)
bc = cl_teambottomcolor;
}
else
{
if (cl_enemytopcolor>=0)
tc = cl_enemytopcolor;
if (cl_enemybottomcolor>=0)
bc = cl_enemybottomcolor;
}
}
}
else
{
tc = 1;
bc = 1;
}
if (tc != 1 || bc != 1 || (e->scoreboard && e->scoreboard->skin))
{
int inwidth, inheight;
int tinwidth, tinheight;
char *skinname;
qbyte *original;
int cc;
galiascolourmapped_t *cm;
char hashname[512];
cc = (tc<<4)|bc;
if (e->scoreboard && e->scoreboard->skin && !gl_nocolors.value)
{
snprintf(hashname, sizeof(hashname), "%s$%s$%i", modelname, e->scoreboard->skin->name, surfnum);
skinname = hashname;
}
else if (surfnum)
{
snprintf(hashname, sizeof(hashname), "%s$%i", modelname, surfnum);
skinname = hashname;
}
else
skinname = modelname;
if (!skincolourmapped.numbuckets)
Hash_InitTable(&skincolourmapped, 256, BZ_Malloc(Hash_BytesForBuckets(256)));
for (cm = Hash_Get(&skincolourmapped, skinname); cm; cm = Hash_GetNext(&skincolourmapped, skinname, cm))
{
if (cm->colour == cc && cm->skinnum == e->skinnum)
{
return &cm->texnum;
}
}
if (!inf->numskins)
{
skins = NULL;
texnums = NULL;
}
else
{
skins = (galiasskin_t*)((char *)inf + inf->ofsskins);
if (!skins->texnums)
{
skins = NULL;
texnums = NULL;
}
else
{
if (e->skinnum >= 0 && e->skinnum < inf->numskins)
skins += e->skinnum;
texnums = (galiastexnum_t*)((char *)skins + skins->ofstexnums);
}
}
//colourmap isn't present yet.
cm = BZ_Malloc(sizeof(*cm));
Q_strncpyz(cm->name, skinname, sizeof(cm->name));
Hash_Add(&skincolourmapped, cm->name, cm, &cm->bucket);
cm->colour = cc;
cm->skinnum = e->skinnum;
cm->texnum.fullbright = 0;
cm->texnum.base = 0;
if (!texnums)
{ //load just the skin (q2)
/* if (e->scoreboard && e->scoreboard->skin)
{
if (cls.protocol == CP_QUAKE2)
{
original = Skin_Cache32(e->scoreboard->skin);
if (original)
{
inwidth = e->scoreboard->skin->width;
inheight = e->scoreboard->skin->height;
cm->texnum.base = cm->texnum.fullbright = GL_LoadTexture32(e->scoreboard->skin->name, inwidth, inheight, (unsigned int*)original, true, false);
return &cm->texnum;
}
}
else
{
original = Skin_Cache8(e->scoreboard->skin);
if (original)
{
inwidth = e->scoreboard->skin->width;
inheight = e->scoreboard->skin->height;
cm->texnum.base = cm->texnum.fullbright = GL_LoadTexture(e->scoreboard->skin->name, inwidth, inheight, original, true, false);
return &cm->texnum;
}
}
cm->texnum.base = Mod_LoadHiResTexture(e->scoreboard->skin->name, "skins", true, false, true);
return &cm->texnum;
}
*/
return NULL;
}
cm->texnum.bump = texnums[cm->skinnum].bump; //can't colour bumpmapping
if (cls.protocol != CP_QUAKE2 && ((!texnums || !strcmp(modelname, "progs/player.mdl")) && e->scoreboard && e->scoreboard->skin))
{
original = Skin_Cache8(e->scoreboard->skin);
inwidth = e->scoreboard->skin->width;
inheight = e->scoreboard->skin->height;
}
else
{
original = NULL;
inwidth = 0;
inheight = 0;
}
if (!original)
{
if (skins->ofstexels)
{
original = (qbyte *)skins + skins->ofstexels;
inwidth = skins->skinwidth;
inheight = skins->skinheight;
}
else
{
original = NULL;
inwidth = 0;
inheight = 0;
}
}
tinwidth = skins->skinwidth;
tinheight = skins->skinheight;
if (original)
{
int i, j;
qbyte translate[256];
unsigned translate32[256];
static unsigned pixels[512*512];
unsigned *out;
unsigned frac, fracstep;
unsigned scaled_width, scaled_height;
qbyte *inrow;
texnums = &cm->texnum;
texnums->base = 0;
texnums->fullbright = 0;
if (gl_max_size.value <= 0)
gl_max_size.value = 512;
scaled_width = gl_max_size.value < 512 ? gl_max_size.value : 512;
scaled_height = gl_max_size.value < 512 ? gl_max_size.value : 512;
for (i=0 ; i<256 ; i++)
translate[i] = i;
tc<<=4;
bc<<=4;
for (i=0 ; i<16 ; i++)
{
if (tc < 128) // the artists made some backwards ranges. sigh.
translate[TOP_RANGE+i] = tc+i;
else
translate[TOP_RANGE+i] = tc+15-i;
if (bc < 128)
translate[BOTTOM_RANGE+i] = bc+i;
else
translate[BOTTOM_RANGE+i] = bc+15-i;
}
for (i=0 ; i<256 ; i++)
translate32[i] = d_8to24rgbtable[translate[i]];
out = pixels;
fracstep = tinwidth*0x10000/scaled_width;
for (i=0 ; i<scaled_height ; i++, out += scaled_width)
{
inrow = original + inwidth*(i*inheight/scaled_height);
frac = fracstep >> 1;
for (j=0 ; j<scaled_width ; j+=4)
{
out[j] = translate32[inrow[frac>>16]] | 0xff000000;
frac += fracstep;
out[j+1] = translate32[inrow[frac>>16]] | 0xff000000;
frac += fracstep;
out[j+2] = translate32[inrow[frac>>16]] | 0xff000000;
frac += fracstep;
out[j+3] = translate32[inrow[frac>>16]] | 0xff000000;
frac += fracstep;
}
}
texnums->base = D3D_LoadTexture_32 ("", pixels, scaled_width, scaled_height, 0);
/* texnums->base = texture_extension_number++;
GL_Bind(texnums->base);
qglTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
*/
//now do the fullbrights.
out = pixels;
fracstep = tinwidth*0x10000/scaled_width;
for (i=0 ; i<scaled_height ; i++, out += scaled_width)
{
inrow = original + inwidth*(i*inheight/scaled_height);
frac = fracstep >> 1;
for (j=0 ; j<scaled_width ; j+=1)
{
if (inrow[frac>>16] < 255-vid.fullbright)
((char *) (&out[j]))[3] = 0; //alpha 0
frac += fracstep;
}
}
/* texnums->fullbright = texture_extension_number++;
GL_Bind(texnums->fullbright);
qglTexImage2D (GL_TEXTURE_2D, 0, gl_alpha_format, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
*/
}
else
{
skins = (galiasskin_t*)((char *)inf + inf->ofsskins);
if (e->skinnum >= 0 && e->skinnum < inf->numskins)
skins += e->skinnum;
if (!inf->numskins || !skins->texnums)
return NULL;
frame = cl.time*skins->skinspeed;
frame = frame%skins->texnums;
texnums = (galiastexnum_t*)((char *)skins + skins->ofstexnums + frame*sizeof(galiastexnum_t));
memcpy(&cm->texnum, texnums, sizeof(cm->texnum));
}
return &cm->texnum;
}
}
if (!inf->numskins)
return NULL;
skins = (galiasskin_t*)((char *)inf + inf->ofsskins);
if (e->skinnum >= 0 && e->skinnum < inf->numskins)
skins += e->skinnum;
else
{
Con_DPrintf("Skin number out of range\n");
if (!inf->numskins)
return NULL;
}
if (!skins->texnums)
return NULL;
frame = cl.time*skins->skinspeed;
frame = frame%skins->texnums;
texnums = (galiastexnum_t*)((char *)skins + skins->ofstexnums + frame*sizeof(galiastexnum_t));
return texnums;
}
extern vec3_t shadevector;
extern vec3_t ambientlight;
extern vec3_t shadelight;
static void LotsOfLightDirectionHacks(entity_t *e, model_t *m, vec3_t lightaxis[3])
{
int i;
vec3_t dist;
float add;
qboolean nolightdir;
vec3_t lightdir;
if (!(r_refdef.flags & Q2RDF_NOWORLDMODEL))
{
if (e->flags & Q2RF_WEAPONMODEL)
cl.worldmodel->funcs.LightPointValues(cl.worldmodel, r_refdef.vieworg, shadelight, ambientlight, lightdir);
else
cl.worldmodel->funcs.LightPointValues(cl.worldmodel, e->origin, shadelight, ambientlight, lightdir);
}
else
{
ambientlight[0] = ambientlight[1] = ambientlight[2] = shadelight[0] = shadelight[1] = shadelight[2] = 255;
lightdir[0] = 0;
lightdir[1] = 1;
lightdir[2] = 1;
}
if (!r_vertexdlights.value)
{
for (i=0 ; i<dlights_running ; i++)
{
if (cl_dlights[i].radius)
{
VectorSubtract (e->origin,
cl_dlights[i].origin,
dist);
add = cl_dlights[i].radius - Length(dist);
if (add > 0) {
add*=5;
ambientlight[0] += add * cl_dlights[i].color[0];
ambientlight[1] += add * cl_dlights[i].color[1];
ambientlight[2] += add * cl_dlights[i].color[2];
//ZOID models should be affected by dlights as well
shadelight[0] += add * cl_dlights[i].color[0];
shadelight[1] += add * cl_dlights[i].color[1];
shadelight[2] += add * cl_dlights[i].color[2];
}
}
}
}
else
{
}
for (i = 0; i < 3; i++) //clamp light so it doesn't get vulgar.
{
if (ambientlight[i] > 128)
ambientlight[i] = 128;
if (ambientlight[i] + shadelight[i] > 192)
shadelight[i] = 192 - ambientlight[i];
}
if (e->flags & Q2RF_WEAPONMODEL)
{
for (i = 0; i < 3; i++)
{
if (ambientlight[i] < 24)
ambientlight[i] = shadelight[i] = 24;
}
}
//MORE HUGE HACKS! WHEN WILL THEY CEASE!
// clamp lighting so it doesn't overbright as much
// ZOID: never allow players to go totally black
nolightdir = false;
if (m->engineflags & MDLF_PLAYER)
{
float fb = r_fullbrightSkins.value;
if (fb > cls.allow_fbskins)
fb = cls.allow_fbskins;
if (fb < 0)
fb = 0;
if (fb)
{
extern cvar_t r_fb_models;
if (fb >= 1 && r_fb_models.value)
{
ambientlight[0] = ambientlight[1] = ambientlight[2] = 4096;
shadelight[0] = shadelight[1] = shadelight[2] = 4096;
nolightdir = true;
}
else
{
for (i = 0; i < 3; i++)
{
ambientlight[i] = max(ambientlight[i], 8 + fb * 120);
shadelight[i] = max(shadelight[i], 8 + fb * 120);
}
}
}
for (i = 0; i < 3; i++)
{
if (ambientlight[i] < 8)
ambientlight[i] = shadelight[i] = 8;
}
}
if (m->engineflags & MDLF_FLAME)
{
shadelight[0] = shadelight[1] = shadelight[2] = 4096;
ambientlight[0] = ambientlight[1] = ambientlight[2] = 4096;
nolightdir = true;
}
else
{
for (i = 0; i < 3; i++)
{
if (ambientlight[i] > 128)
ambientlight[i] = 128;
shadelight[i] /= 200.0/255;
ambientlight[i] /= 200.0/255;
}
}
if ((e->drawflags & MLS_MASKIN) == MLS_ABSLIGHT)
{
shadelight[0] = shadelight[1] = shadelight[2] = e->abslight;
ambientlight[0] = ambientlight[1] = ambientlight[2] = 0;
}
if ((e->drawflags & MLS_MASKIN) == MLS_FULLBRIGHT || (e->flags & Q2RF_FULLBRIGHT))
{
shadelight[0] = shadelight[1] = shadelight[2] = 255;
ambientlight[0] = ambientlight[1] = ambientlight[2] = 0;
nolightdir = true;
}
//#define SHOWLIGHTDIR
{ //lightdir is absolute, shadevector is relative
shadevector[0] = DotProduct(lightdir, e->axis[0]);
shadevector[1] = DotProduct(lightdir, e->axis[1]);
shadevector[2] = DotProduct(lightdir, e->axis[2]);
if (e->flags & Q2RF_WEAPONMODEL)
{
vec3_t temp;
temp[0] = DotProduct(shadevector, vpn);
temp[1] = DotProduct(shadevector, vright);
temp[2] = DotProduct(shadevector, vup);
VectorCopy(temp, shadevector);
}
VectorNormalize(shadevector);
VectorCopy(shadevector, lightaxis[2]);
VectorVectors(lightaxis[2], lightaxis[1], lightaxis[0]);
VectorInverse(lightaxis[1]);
}
if (e->flags & Q2RF_GLOW)
{
shadelight[0] += sin(cl.time)*0.25;
shadelight[1] += sin(cl.time)*0.25;
shadelight[2] += sin(cl.time)*0.25;
}
//d3d is bgra
//ogl is rgba
//so switch em and use the gl code
add = shadelight[0];
shadelight[0] = shadelight[2];
shadelight[2] = add;
add = ambientlight[0];
ambientlight[0] = ambientlight[2];
ambientlight[2] = add;
}
qboolean R_GAliasBuildMesh(mesh_t *mesh, galiasinfo_t *inf, int frame1, int frame2, float lerp, float alpha, float fg1time, float fg2time, qboolean nolightdir);
//draws currententity
void D3D_DrawAliasModel(void)
{
mesh_t mesh;
extern entity_t *currententity;
entity_t *e = currententity;
galiasinfo_t *inf;
model_t *m;
galiastexnum_t *skin;
int i;
if (r_secondaryview && e->flags & Q2RF_WEAPONMODEL)
return;
{
extern int cl_playerindex;
if (e->scoreboard && e->model == cl.model_precache[cl_playerindex])
{
m = e->scoreboard->model;
if (!m || m->type != mod_alias)
m = e->model;
}
else
m = e->model;
}
if (!(e->flags & Q2RF_WEAPONMODEL))
if (R_CullEntityBox (e, m->mins, m->maxs))
return;
inf = GLMod_Extradata (m);
if (!inf)
return;
LotsOfLightDirectionHacks(e, m, mesh.lightaxis);
{
float matrix[16];
if (e->flags & Q2RF_WEAPONMODEL && r_refdef.currentplayernum>=0)
{ //view weapons need to be rotated onto the screen first
float view[16];
float ent[16];
Matrix4_ModelMatrixFromAxis(view, cl.viewent[r_refdef.currentplayernum].axis[0], cl.viewent[r_refdef.currentplayernum].axis[1], cl.viewent[r_refdef.currentplayernum].axis[2], cl.viewent[r_refdef.currentplayernum].origin);
Matrix4_ModelMatrixFromAxis(ent, e->axis[0], e->axis[1], e->axis[2], e->origin);
Matrix4_Multiply(view, ent, matrix);
}
else
{
Matrix4_ModelMatrixFromAxis(matrix, e->axis[0], e->axis[1], e->axis[2], e->origin);
}
pD3DDev->lpVtbl->SetTransform(pD3DDev, D3DTRANSFORMSTATE_WORLD, (D3DMATRIX*)matrix);
}
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
if (e->flags & Q2RF_DEPTHHACK)
{ //apply the depth hack to stop things from poking into walls.
//(basically moving it closer to the screen)
D3DVIEWPORT7 viewport;
pD3DDev->lpVtbl->GetViewport(pD3DDev, &viewport);
viewport.dvMinZ = 0;
viewport.dvMaxZ = 0.3;
pD3DDev->lpVtbl->SetViewport(pD3DDev, &viewport);
}
for(i = 0;; i++)
{
R_GAliasBuildMesh(&mesh, inf, e->frame, e->oldframe, e->lerpfrac, e->shaderRGBAf[3], e->frame1time, e->frame2time, 0);
skin = D3D_ChooseSkin(inf, m->name, e->skinnum, e);
if (!skin)
pD3DDev->lpVtbl->SetTexture(pD3DDev, 0, NULL);
else
pD3DDev->lpVtbl->SetTexture(pD3DDev, 0, skin->base);
D3D_DrawMesh(&mesh);
if (inf->nextsurf == 0)
break;
inf = (galiasinfo_t*)((char*)inf + inf->nextsurf);
}
if (e->flags & Q2RF_DEPTHHACK)
{
D3DVIEWPORT7 viewport;
pD3DDev->lpVtbl->GetViewport(pD3DDev, &viewport);
viewport.dvMinZ = 0;
viewport.dvMaxZ = 1;
pD3DDev->lpVtbl->SetViewport(pD3DDev, &viewport);
}
{
float matrix[16];
Matrix4_Identity(matrix);
pD3DDev->lpVtbl->SetTransform(pD3DDev, D3DTRANSFORMSTATE_WORLD, (D3DMATRIX*)matrix);
}
}
#endif

964
engine/d3d/d3d_rmain.c Normal file
View file

@ -0,0 +1,964 @@
#include "quakedef.h"
#ifdef D3DQUAKE
#include "d3dquake.h"
mleaf_t *r_viewleaf, *r_oldviewleaf;
mleaf_t *r_viewleaf2, *r_oldviewleaf2;
int r_viewcluster, r_viewcluster2, r_oldviewcluster, r_oldviewcluster2;
extern qbyte areabits[MAX_Q2MAP_AREAS/8];
int r_visframecount;
entity_t r_worldentity;
refdef_t r_refdef;
vec3_t r_origin, vpn, vright, vup;
extern float r_projection_matrix[16];
extern float r_view_matrix[16];
//mplane_t frustum[4];
vec3_t modelorg;
entity_t *currententity;
extern cvar_t gl_mindist;
void (D3D_R_DeInit) (void)
{
}
void (D3D_R_ReInit) (void)
{
}
void (D3D_R_Init) (void)
{
D3D_R_ReInit();
}
//most of this is a direct copy from gl
void (D3D_SetupFrame) (void)
{
mleaf_t *leaf;
vec3_t temp;
GLR_AnimateLight();
AngleVectors (r_refdef.viewangles, vpn, vright, vup);
VectorCopy (r_refdef.vieworg, r_origin);
r_framecount++;
r_oldviewleaf = r_viewleaf;
r_oldviewleaf2 = r_viewleaf2;
r_viewleaf = GLMod_PointInLeaf (cl.worldmodel, r_origin);
if (!r_viewleaf)
{
}
else if (r_viewleaf->contents == Q1CONTENTS_EMPTY)
{ //look down a bit
VectorCopy (r_origin, temp);
temp[2] -= 16;
leaf = GLMod_PointInLeaf (cl.worldmodel, temp);
if (leaf->contents <= Q1CONTENTS_WATER && leaf->contents >= Q1CONTENTS_LAVA)
r_viewleaf2 = leaf;
else
r_viewleaf2 = NULL;
}
else if (r_viewleaf->contents <= Q1CONTENTS_WATER && r_viewleaf->contents >= Q1CONTENTS_LAVA)
{ //in water, look up a bit.
VectorCopy (r_origin, temp);
temp[2] += 16;
leaf = GLMod_PointInLeaf (cl.worldmodel, temp);
if (leaf->contents == Q1CONTENTS_EMPTY)
r_viewleaf2 = leaf;
else
r_viewleaf2 = NULL;
}
else
r_viewleaf2 = NULL;
if (r_viewleaf)
V_SetContentsColor (r_viewleaf->contents);
}
void D3D_SetupViewPort(void)
{
float screenaspect;
int glwidth = vid.width, glheight=vid.height;
int x, x2, y2, y, w, h;
float fov_x, fov_y;
D3DVIEWPORT7 vport;
D3D_GetBufferSize(&glwidth, &glheight);
//
// set up viewpoint
//
x = r_refdef.vrect.x * glwidth/(int)vid.width;
x2 = (r_refdef.vrect.x + r_refdef.vrect.width) * glwidth/(int)vid.width;
y = (/*vid.height-*/r_refdef.vrect.y) * glheight/(int)vid.height;
y2 = ((int)/*vid.height - */(r_refdef.vrect.y + r_refdef.vrect.height)) * glheight/(int)vid.height;
// fudge around because of frac screen scale
if (x > 0)
x--;
if (x2 < glwidth)
x2++;
if (y < 0)
y--;
if (y2 < glheight)
y2++;
w = x2 - x;
h = y2 - y;
/* if (envmap)
{
x = y2 = 0;
w = h = 256;
}
*/
vport.dwX = x;
vport.dwY = y;
vport.dwWidth = w;
vport.dwHeight = h;
vport.dvMinZ = 0;
vport.dvMaxZ = 1;
pD3DDev->lpVtbl->SetViewport(pD3DDev, &vport);
fov_x = r_refdef.fov_x;//+sin(cl.time)*5;
fov_y = r_refdef.fov_y;//-sin(cl.time+1)*5;
if (r_waterwarp.value<0 && r_viewleaf->contents <= Q1CONTENTS_WATER)
{
fov_x *= 1 + (((sin(cl.time * 4.7) + 1) * 0.015) * r_waterwarp.value);
fov_y *= 1 + (((sin(cl.time * 3.0) + 1) * 0.015) * r_waterwarp.value);
}
screenaspect = (float)r_refdef.vrect.width/r_refdef.vrect.height;
// if (r_refdef.useperspective)
{
/* if ((!r_shadows.value || !gl_canstencil) && gl_maxdist.value>256)//gl_nv_range_clamp)
{
// yfov = 2*atan((float)r_refdef.vrect.height/r_refdef.vrect.width)*180/M_PI;
// yfov = (2.0 * tan (scr_fov.value/360*M_PI)) / screenaspect;
// yfov = 2*atan((float)r_refdef.vrect.height/r_refdef.vrect.width)*(scr_fov.value*2)/M_PI;
// MYgluPerspective (yfov, screenaspect, 4, 4096);
MYgluPerspective (fov_x, fov_y, gl_mindist.value, gl_maxdist.value);
}
else*/
{
GL_InfinatePerspective(fov_x, fov_y, gl_mindist.value);
}
}
/* else
{
if (gl_maxdist.value>=1)
GL_ParallelPerspective(-fov_x/2, fov_x/2, fov_y/2, -fov_y/2, -gl_maxdist.value, gl_maxdist.value);
else
GL_ParallelPerspective(0, r_refdef.vrect.width, 0, r_refdef.vrect.height, -9999, 9999);
}*/
Matrix4_ModelViewMatrixFromAxis(r_view_matrix, vpn, vright, vup, r_refdef.vieworg);
pD3DDev->lpVtbl->SetTransform(pD3DDev, D3DTRANSFORMSTATE_PROJECTION, (D3DMATRIX*)r_projection_matrix);
pD3DDev->lpVtbl->SetTransform(pD3DDev, D3DTRANSFORMSTATE_VIEW, (D3DMATRIX*)r_view_matrix);
pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ZFUNC, D3DCMP_LESSEQUAL);
pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ZENABLE, D3DZB_TRUE);
}
qbyte *Q1BSP_LeafPVS (model_t *model, mleaf_t *leaf, qbyte *buffer);
//fixme: direct copy from gl (apart from lightmaps)
static void D3D7_RecursiveWorldNode (mnode_t *node)
{
int c, side;
mplane_t *plane;
msurface_t *surf, **mark;
mleaf_t *pleaf;
double dot;
int shift;
start:
if (node->contents == Q1CONTENTS_SOLID)
return; // solid
if (node->visframe != r_visframecount)
return;
if (R_CullBox (node->minmaxs, node->minmaxs+3))
return;
// if a leaf node, draw stuff
if (node->contents < 0)
{
pleaf = (mleaf_t *)node;
mark = pleaf->firstmarksurface;
c = pleaf->nummarksurfaces;
if (c)
{
do
{
(*mark++)->visframe = r_framecount;
} while (--c);
}
// deal with model fragments in this leaf
if (pleaf->efrags)
R_StoreEfrags (&pleaf->efrags);
return;
}
// node is just a decision point, so go down the apropriate sides
// find which side of the node we are on
plane = node->plane;
switch (plane->type)
{
case PLANE_X:
dot = modelorg[0] - plane->dist;
break;
case PLANE_Y:
dot = modelorg[1] - plane->dist;
break;
case PLANE_Z:
dot = modelorg[2] - plane->dist;
break;
default:
dot = DotProduct (modelorg, plane->normal) - plane->dist;
break;
}
if (dot >= 0)
side = 0;
else
side = 1;
// recurse down the children, front side first
D3D7_RecursiveWorldNode (node->children[side]);
// draw stuff
c = node->numsurfaces;
if (c)
{
surf = cl.worldmodel->surfaces + node->firstsurface;
shift = 0;//GLR_LightmapShift(cl.worldmodel);
// if (dot < 0 -BACKFACE_EPSILON)
// side = SURF_PLANEBACK;
// else if (dot > BACKFACE_EPSILON)
// side = 0;
{
for ( ; c ; c--, surf++)
{
if (surf->visframe != r_framecount)
continue;
// if (((dot < 0) ^ !!(surf->flags & SURF_PLANEBACK)))
// continue; // wrong side
D3DR_RenderDynamicLightmaps (surf, shift);
// if sorting by texture, just store it out
/* if (surf->flags & SURF_DRAWALPHA)
{ // add to the translucent chain
surf->nextalphasurface = r_alpha_surfaces;
r_alpha_surfaces = surf;
surf->ownerent = &r_worldentity;
}
else
*/ {
surf->texturechain = surf->texinfo->texture->texturechain;
surf->texinfo->texture->texturechain = surf;
}
}
}
}
// recurse down the back side
// GLR_RecursiveWorldNode (node->children[!side]);
node = node->children[!side];
goto start;
}
struct {
float x, y, z;
// unsigned colour;
float wms, wmt;
float lms, lmt;
} worldvert[64];
void D3D_DrawTextureChains(void)
{
texture_t *t;
msurface_t *s;
vec3_t *xyz;
vec2_t *wm;
vec2_t *lm;
mesh_t *m;
int i;
int v;
int lmnum;
extern int skytexturenum; // index in cl.loadmodel, not gl texture object
if (skytexturenum>=0)
{
t = currentmodel->textures[skytexturenum];
if (t)
{
s = t->texturechain;
if (s)
{
t->texturechain = NULL;
D3D7_DrawSkyChain (s);
}
}
}
pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHATESTENABLE, FALSE );
for (i = 0; i < currentmodel->numtextures; i++)
{
t = currentmodel->textures[i];
if (!t)
continue; //happens on e1m2
s = t->texturechain;
if (!s)
continue;
t->texturechain = NULL;
pD3DDev->lpVtbl->SetTexture(pD3DDev, 0, (LPDIRECTDRAWSURFACE7)t->gl_texturenum);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_TEXCOORDINDEX, 0);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
while(s)
{
m = s->mesh;
if (m)
{
lmnum = s->lightmaptexturenum;
if (lmnum >= 0)
{
if (lightmap[lmnum]->modified)
{
DDSURFACEDESC2 desc;
desc.dwSize = sizeof(desc);
lightmap_d3dtextures[lmnum]->lpVtbl->Lock(lightmap_d3dtextures[lmnum], NULL, &desc, DDLOCK_NOSYSLOCK|DDLOCK_WAIT|DDLOCK_WRITEONLY|DDLOCK_DISCARDCONTENTS, NULL);
memcpy(desc.lpSurface, lightmap[lmnum]->lightmaps, LMBLOCK_WIDTH*LMBLOCK_HEIGHT*4);
/* {
int i;
unsigned char *c;
unsigned char v;
c = desc.lpSurface;
for (i = 0; i < LMBLOCK_WIDTH*LMBLOCK_HEIGHT; i++)
{
v = rand();
*c++ = v;
*c++ = v;
*c++ = v;
c++;
}
}*/
lightmap_d3dtextures[lmnum]->lpVtbl->Unlock(lightmap_d3dtextures[lmnum], NULL);
lightmap[lmnum]->modified = false;
}
pD3DDev->lpVtbl->SetTexture(pD3DDev, 1, (LPDIRECTDRAWSURFACE7)lightmap_d3dtextures[lmnum]);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_COLOROP, D3DTOP_MODULATE);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_TEXCOORDINDEX, 1);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
}
else
{
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
}
//pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
xyz = m->xyz_array;
wm = m->st_array;
lm = m->lmst_array;
for (v = 0; v < m->numvertexes; v++, xyz++, wm++, lm++)
{
worldvert[v].x = (*xyz)[0];
worldvert[v].y = (*xyz)[1];
worldvert[v].z = (*xyz)[2];
// worldvert[v].colour = 0;
worldvert[v].wms = (*wm)[0];
worldvert[v].wmt = (*wm)[1];
worldvert[v].lms = (*lm)[0];
worldvert[v].lmt = (*lm)[1];
}
pD3DDev->lpVtbl->DrawIndexedPrimitive(pD3DDev, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_TEX2, worldvert, m->numvertexes, m->indexes, m->numindexes, 0);
}
s = s->texturechain;
}
}
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHATESTENABLE, TRUE );
}
void D3D_BaseBModelTextures(entity_t *e)
{
texture_t *t;
msurface_t *s;
vec3_t *xyz;
vec2_t *wm;
vec2_t *lm;
mesh_t *m;
int i;
int v;
float matrix[16];
int lmnum = -1;
currentmodel = e->model;
for (s = currentmodel->surfaces+currentmodel->firstmodelsurface, i = 0; i < currentmodel->nummodelsurfaces; i++, s++)
{
t = R_TextureAnimation(s->texinfo->texture);
{
m = s->mesh;
if (m)
D3DR_RenderDynamicLightmaps (s, 0);
}
}
Matrix4_ModelMatrixFromAxis(matrix, e->axis[0], e->axis[1], e->axis[2], e->origin);
pD3DDev->lpVtbl->SetTransform(pD3DDev, D3DTRANSFORMSTATE_WORLD, (D3DMATRIX*)matrix);
pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHATESTENABLE, FALSE );
for (s = currentmodel->surfaces+currentmodel->firstmodelsurface, i = 0; i < currentmodel->nummodelsurfaces; i++, s++)
{
t = R_TextureAnimation(s->texinfo->texture);
pD3DDev->lpVtbl->SetTexture(pD3DDev, 0, (LPDIRECTDRAWSURFACE7)t->gl_texturenum);
pD3DDev->lpVtbl->SetTexture(pD3DDev, 1, (LPDIRECTDRAWSURFACE7)lightmap_d3dtextures[s->lightmaptexturenum]);
{
m = s->mesh;
if (m)
{
if (lmnum != s->lightmaptexturenum)
{
lmnum = s->lightmaptexturenum;
if (lmnum >= 0)
{
if (lightmap[lmnum]->modified)
{
DDSURFACEDESC2 desc;
desc.dwSize = sizeof(desc);
lightmap_d3dtextures[lmnum]->lpVtbl->Lock(lightmap_d3dtextures[lmnum], NULL, &desc, DDLOCK_NOSYSLOCK|DDLOCK_WAIT|DDLOCK_WRITEONLY|DDLOCK_DISCARDCONTENTS, NULL);
memcpy(desc.lpSurface, lightmap[lmnum]->lightmaps, LMBLOCK_WIDTH*LMBLOCK_HEIGHT*4);
/* {
int i;
unsigned char *c;
unsigned char v;
c = desc.lpSurface;
for (i = 0; i < LMBLOCK_WIDTH*LMBLOCK_HEIGHT; i++)
{
v = rand();
*c++ = v;
*c++ = v;
*c++ = v;
c++;
}
}*/
lightmap_d3dtextures[lmnum]->lpVtbl->Unlock(lightmap_d3dtextures[lmnum], NULL);
lightmap[lmnum]->modified = false;
}
pD3DDev->lpVtbl->SetTexture(pD3DDev, 1, (LPDIRECTDRAWSURFACE7)lightmap_d3dtextures[lmnum]);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_COLOROP, D3DTOP_MODULATE);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_TEXCOORDINDEX, 1);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
}
else
{
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
}
}
xyz = m->xyz_array;
wm = m->st_array;
lm = m->lmst_array;
for (v = 0; v < m->numvertexes; v++, xyz++, wm++, lm++)
{
worldvert[v].x = (*xyz)[0];
worldvert[v].y = (*xyz)[1];
worldvert[v].z = (*xyz)[2];
// worldvert[v].colour = 0;
worldvert[v].wms = (*wm)[0];
worldvert[v].wmt = (*wm)[1];
worldvert[v].lms = (*lm)[0];
worldvert[v].lmt = (*lm)[1];
}
pD3DDev->lpVtbl->DrawIndexedPrimitive(pD3DDev, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_TEX2, worldvert, m->numvertexes, m->indexes, m->numindexes, 0);
}
}
}
pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHATESTENABLE, TRUE );
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
pD3DDev->lpVtbl->SetTransform(pD3DDev, D3DTRANSFORMSTATE_WORLD, (D3DMATRIX*)matrix);
}
typedef struct {
float pos[3];
int colour;
float tc[2];
} d3dvert_t;
/*
================
R_GetSpriteFrame
================
*/
/*
mspriteframe_t *R_GetSpriteFrame (entity_t *currententity)
{
msprite_t *psprite;
mspritegroup_t *pspritegroup;
mspriteframe_t *pspriteframe;
int i, numframes, frame;
float *pintervals, fullinterval, targettime, time;
psprite = currententity->model->cache.data;
frame = currententity->frame;
if ((frame >= psprite->numframes) || (frame < 0))
{
Con_DPrintf ("R_DrawSprite: no such frame %d (%s)\n", frame, currententity->model->name);
frame = 0;
}
if (psprite->frames[frame].type == SPR_SINGLE)
{
pspriteframe = psprite->frames[frame].frameptr;
}
else if (psprite->frames[frame].type == SPR_ANGLED)
{
pspritegroup = (mspritegroup_t *)psprite->frames[frame].frameptr;
pspriteframe = pspritegroup->frames[(int)((r_refdef.viewangles[1]-currententity->angles[1])/360*8 + 0.5-4)&7];
}
else
{
pspritegroup = (mspritegroup_t *)psprite->frames[frame].frameptr;
pintervals = pspritegroup->intervals;
numframes = pspritegroup->numframes;
fullinterval = pintervals[numframes-1];
time = currententity->frame1time;
// when loading in Mod_LoadSpriteGroup, we guaranteed all interval values
// are positive, so we don't have to worry about division by 0
targettime = time - ((int)(time / fullinterval)) * fullinterval;
for (i=0 ; i<(numframes-1) ; i++)
{
if (pintervals[i] > targettime)
break;
}
pspriteframe = pspritegroup->frames[i];
}
return pspriteframe;
}
*/
static void D3D_DrawSpriteModel (entity_t *e)
{
vec3_t point;
mspriteframe_t *frame;
vec3_t forward, right, up;
msprite_t *psprite;
qbyte coloursb[4];
d3dvert_t d3dvert[4];
index_t vertindexes[6] = {
0, 1, 2,
0, 2, 3
};
if (!e->model)
return;
if (e->flags & RF_NODEPTHTEST)
pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ZFUNC, D3DCMP_ALWAYS);
// don't even bother culling, because it's just a single
// polygon without a surface cache
frame = R_GetSpriteFrame (e);
psprite = e->model->cache.data;
// frame = 0x05b94140;
switch(psprite->type)
{
case SPR_ORIENTED:
// bullet marks on walls
AngleVectors (e->angles, forward, right, up);
break;
case SPR_FACING_UPRIGHT:
up[0] = 0;up[1] = 0;up[2]=1;
right[0] = e->origin[1] - r_origin[1];
right[1] = -(e->origin[0] - r_origin[0]);
right[2] = 0;
VectorNormalize (right);
break;
case SPR_VP_PARALLEL_UPRIGHT:
up[0] = 0;up[1] = 0;up[2]=1;
VectorCopy (vright, right);
break;
default:
case SPR_VP_PARALLEL:
//normal sprite
VectorCopy(vup, up);
VectorCopy(vright, right);
break;
}
up[0]*=e->scale;
up[1]*=e->scale;
up[2]*=e->scale;
right[0]*=e->scale;
right[1]*=e->scale;
right[2]*=e->scale;
pD3DDev->lpVtbl->SetTexture(pD3DDev, 0, (LPDIRECTDRAWSURFACE7)frame->gl_texturenum);
/* {
extern int gldepthfunc;
qglDepthFunc(gldepthfunc);
qglDepthMask(0);
if (gldepthmin == 0.5)
qglCullFace ( GL_BACK );
else
qglCullFace ( GL_FRONT );
GL_TexEnv(GL_MODULATE);
qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
qglDisable (GL_ALPHA_TEST);
qglDisable(GL_BLEND);
}*/
/* if (e->flags & Q2RF_ADDATIVE)
{
qglEnable(GL_BLEND);
qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
qglBlendFunc(GL_SRC_ALPHA, GL_ONE);
}
else if (e->shaderRGBAf[3]<1 || gl_blendsprites.value)
{
qglEnable(GL_BLEND);
qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}
else
qglEnable (GL_ALPHA_TEST);
*/
d3dvert[0].colour = 0xffffffff;
d3dvert[0].tc[0] = 0;
d3dvert[0].tc[1] = 1;
VectorMA (e->origin, frame->down, up, point);
VectorMA (point, frame->left, right, d3dvert[0].pos);
d3dvert[1].colour = 0xffffffff;
d3dvert[1].tc[0] = 0;
d3dvert[1].tc[0] = 0;
VectorMA (e->origin, frame->up, up, point);
VectorMA (point, frame->left, right, d3dvert[1].pos);
d3dvert[2].colour = 0xffffffff;
d3dvert[2].tc[0] = 1;
d3dvert[2].tc[1] = 0;
VectorMA (e->origin, frame->up, up, point);
VectorMA (point, frame->right, right, d3dvert[2].pos);
d3dvert[3].colour = 0xffffffff;
d3dvert[3].tc[0] = 1;
d3dvert[3].tc[1] = 1;
VectorMA (e->origin, frame->down, up, point);
VectorMA (point, frame->right, right, d3dvert[3].pos);
pD3DDev->lpVtbl->DrawIndexedPrimitive(pD3DDev, D3DPT_TRIANGLEFAN, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1, d3dvert, 4, vertindexes, 6, 0);
if (e->flags & RF_NODEPTHTEST)
pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ZFUNC, D3DCMP_LESSEQUAL);
// if (e->flags & Q2RF_ADDATIVE) //back to regular blending for us!
// qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
//==================================================================================
void D3DR_DrawSprite(void *e, void *parm)
{
currententity = e;
D3D_DrawSpriteModel (currententity);
// P_FlushRenderer();
}
qboolean D3D_ShouldDraw(void)
{
{
if (currententity->flags & Q2RF_EXTERNALMODEL)
return false;
// if (currententity->keynum == (cl.viewentity[r_refdef.currentplayernum]?cl.viewentity[r_refdef.currentplayernum]:(cl.playernum[r_refdef.currentplayernum]+1)))
// return false;
// if (cl.viewentity[r_refdef.currentplayernum] && currententity->keynum == cl.viewentity[r_refdef.currentplayernum])
// continue;
if (!Cam_DrawPlayer(r_refdef.currentplayernum, currententity->keynum-1))
return false;
}
return true;
}
void D3DR_DrawEntitiesOnList (void)
{
int i;
if (!r_drawentities.value)
return;
// draw sprites seperately, because of alpha blending
for (i=0 ; i<cl_numvisedicts ; i++)
{
currententity = &cl_visedicts[i];
if (!D3D_ShouldDraw())
continue;
switch (currententity->rtype)
{
case RT_SPRITE:
RQ_AddDistReorder(D3DR_DrawSprite, currententity, NULL, currententity->origin);
continue;
#ifdef Q3SHADERS
case RT_BEAM:
case RT_RAIL_RINGS:
case RT_LIGHTNING:
R_DrawLightning(currententity);
continue;
case RT_RAIL_CORE:
R_DrawRailCore(currententity);
continue;
#endif
case RT_MODEL: //regular model
break;
case RT_PORTALSURFACE:
continue; //this doesn't do anything anyway, does it?
default:
case RT_POLY: //these are a little painful, we need to do them some time... just not yet.
continue;
}
if (currententity->flags & Q2RF_BEAM)
{
// R_DrawBeam(currententity);
continue;
}
if (!currententity->model)
continue;
if (cl.lerpents && (cls.allow_anyparticles || currententity->visframe)) //allowed or static
{
/* if (gl_part_flame.value)
{
if (currententity->model->engineflags & MDLF_ENGULPHS)
continue;
}*/
}
switch (currententity->model->type)
{
case mod_alias:
// if (r_refdef.flags & Q2RDF_NOWORLDMODEL || !cl.worldmodel || cl.worldmodel->type != mod_brush || cl.worldmodel->fromgame == fg_doom)
D3D_DrawAliasModel ();
break;
#ifdef HALFLIFEMODELS
case mod_halflife:
R_DrawHLModel (currententity);
break;
#endif
case mod_brush:
// if (!cl.worldmodel || cl.worldmodel->type != mod_brush || cl.worldmodel->fromgame == fg_doom)
D3D_BaseBModelTextures (currententity);
break;
case mod_sprite:
RQ_AddDistReorder(D3DR_DrawSprite, currententity, NULL, currententity->origin);
break;
/*
#ifdef TERRAIN
case mod_heightmap:
D3D_DrawHeightmapModel(currententity);
break;
#endif
*/
default:
break;
}
}
{
float m_identity[16] = {
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
};
pD3DDev->lpVtbl->SetTransform(pD3DDev, D3DTRANSFORMSTATE_WORLD, (D3DMATRIX*)m_identity);
}
}
void D3D_DrawWorld(void)
{
RSpeedLocals();
entity_t ent;
memset (&ent, 0, sizeof(ent));
ent.model = cl.worldmodel;
currentmodel = cl.worldmodel;
VectorCopy (r_refdef.vieworg, modelorg);
currententity = &ent;
#ifdef TERRAIN
if (currentmodel->type == mod_heightmap)
GL_DrawHeightmapModel(currententity);
else
#endif
{
// qglColor3f (1,1,1);
//#ifdef QUAKE2
// R_ClearSkyBox ();
//#endif
RSpeedRemark();
/*
#ifdef Q2BSPS
if (ent.model->fromgame == fg_quake2 || ent.model->fromgame == fg_quake3)
{
int leafnum;
int clientarea;
#ifdef QUAKE2
if (cls.protocol == CP_QUAKE2) //we can get server sent info
memcpy(areabits, cl.q2frame.areabits, sizeof(areabits));
else
#endif
{ //generate the info each frame.
leafnum = CM_PointLeafnum (cl.worldmodel, r_refdef.vieworg);
clientarea = CM_LeafArea (cl.worldmodel, leafnum);
CM_WriteAreaBits(cl.worldmodel, areabits, clientarea);
}
#ifdef Q3BSPS
if (ent.model->fromgame == fg_quake3)
{
D3D7_LeafWorldNode ();
}
else
#endif
D3D7_RecursiveQ2WorldNode (cl.worldmodel->nodes);
}
else
#endif
*/
D3D7_RecursiveWorldNode (cl.worldmodel->nodes);
RSpeedEnd(RSPEED_WORLDNODE);
TRACE(("dbg: calling PPL_DrawWorld\n"));
// if (r_shadows.value >= 2 && gl_canstencil && gl_mtexable)
D3D_DrawTextureChains();
// else
// DrawTextureChains (cl.worldmodel, 1, r_refdef.vieworg);
//qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
// GLR_LessenStains();
}
}
void D3D_R_RenderScene(void)
{
if (!cl.worldmodel || (!cl.worldmodel->nodes && cl.worldmodel->type != mod_heightmap))
r_refdef.flags |= Q2RDF_NOWORLDMODEL;
if (!(r_refdef.flags & Q2RDF_NOWORLDMODEL))
{
R_MarkLeaves (); // done here so we know if we're in water
D3D_DrawWorld (); // adds static entities to the list
}
D3DR_DrawEntitiesOnList ();
P_DrawParticles();
}
void (D3D_R_RenderView) (void)
{
D3D_SetupFrame();
D3D_SetupViewPort();
R_SetFrustum();
D3D_R_RenderScene();
}
#endif

1369
engine/d3d/d3d_rsurf.c Normal file

File diff suppressed because it is too large Load diff

73
engine/d3d/d3dquake.h Normal file
View file

@ -0,0 +1,73 @@
#include "ddraw.h"
#include "d3d.h"
#include "d3dx.h"
void *D3D_LoadTexture_32(char *name, unsigned int *data, int width, int height, int flags);
void *D3D_LoadTexture_8_Pal24(char *name, unsigned char *data, int width, int height, int flags, unsigned char *palette, int transparentpix);
void *D3D_LoadTexture_8_Pal32(char *name, unsigned char *data, int width, int height, int flags, unsigned char *palette);
/*
#define D3D9_LoadTexture8Pal32(skinname,width,height,data,palette,usemips,alpha) (int)D3D9_LoadTexture_8_Pal32(skinname, data, width, height, (usemips?TF_MIPMAP:TF_NOMIPMAP) | (alpha?TF_ALPHA:TF_NOALPHA) | TF_NOTBUMPMAP, host_basepal)
#define D3D9_LoadTexture(skinname,width,height,data,usemips,alpha) (int)D3D9_LoadTexture_8_Pal24(skinname, data, width, height, (usemips?TF_MIPMAP:TF_NOMIPMAP) | (alpha?TF_ALPHA:TF_NOALPHA) | TF_NOTBUMPMAP, host_basepal, 255)
#define D3D9_LoadTexture32(skinname,width,height,data,usemips,alpha) (int)D3D9_LoadTexture_32(skinname, data, width, height, (usemips?TF_MIPMAP:TF_NOMIPMAP) | (alpha?TF_ALPHA:TF_NOALPHA) | TF_NOTBUMPMAP)
#define D3D9_LoadTextureFB(skinname,width,height,data,usemips,alpha) 0
#define D3D9_LoadTexture8Bump(skinname,width,height,data,usemips,alpha) 0
#define D3D9_FindTexture(name) -1
#define D3D9_LoadCompressed(name) 0
*/
void *D3D9_LoadTexture_32(char *name, unsigned int *data, int width, int height, int flags);
void *D3D9_LoadTexture_8_Pal24(char *name, unsigned char *data, int width, int height, int flags, unsigned char *palette, int transparentpix);
void *D3D9_LoadTexture_8_Pal32(char *name, unsigned char *data, int width, int height, int flags, unsigned char *palette);
#define D3D_LoadTexture8Pal32(skinname,width,height,data,palette,usemips,alpha) (int)(pD3DDev?D3D_LoadTexture_8_Pal32:D3D9_LoadTexture_8_Pal32)(skinname, data, width, height, (usemips?TF_MIPMAP:TF_NOMIPMAP) | (alpha?TF_ALPHA:TF_NOALPHA) | TF_NOTBUMPMAP, palette)
#define D3D_LoadTexture8Pal24(skinname,width,height,data,palette,usemips,alpha) (int)(pD3DDev?D3D_LoadTexture_8_Pal24:D3D9_LoadTexture_8_Pal24)(skinname, data, width, height, (usemips?TF_MIPMAP:TF_NOMIPMAP) | (alpha?TF_ALPHA:TF_NOALPHA) | TF_NOTBUMPMAP, palette, 255)
#define D3D_LoadTexture(skinname,width,height,data,usemips,alpha) (int)(pD3DDev?D3D_LoadTexture_8_Pal24:D3D9_LoadTexture_8_Pal24)(skinname, data, width, height, (usemips?TF_MIPMAP:TF_NOMIPMAP) | (alpha?TF_ALPHA:TF_NOALPHA) | TF_NOTBUMPMAP, host_basepal, 255)
#define D3D_LoadTexture32(skinname,width,height,data,usemips,alpha) (int)(pD3DDev?D3D_LoadTexture_32:D3D9_LoadTexture_32)(skinname, data, width, height, (usemips?TF_MIPMAP:TF_NOMIPMAP) | (alpha?TF_ALPHA:TF_NOALPHA) | TF_NOTBUMPMAP)
#define D3D_LoadTextureFB(skinname,width,height,data,usemips,alpha) 0
#define D3D_LoadTexture8Bump(skinname,width,height,data,usemips,alpha) 0
#define D3D_FindTexture(name) -1
#define D3D_LoadCompressed(name) 0
extern LPDIRECT3DDEVICE7 pD3DDev;
extern int d_lightstylevalue[256]; // 8.8 fraction of base light value
#define lightmap_bytes 4
extern int numlightmaps;
extern mvertex_t *r_pcurrentvertbase;
#ifndef LMBLOCK_WIDTH
#define LMBLOCK_WIDTH 128
#define LMBLOCK_HEIGHT LMBLOCK_WIDTH
typedef struct glRect_s {
unsigned char l,t,w,h;
} glRect_t;
typedef unsigned char stmap;
typedef struct {
qboolean modified;
qboolean deluxmodified;
glRect_t rectchange;
glRect_t deluxrectchange;
int allocated[LMBLOCK_WIDTH];
qbyte lightmaps[4*LMBLOCK_WIDTH*LMBLOCK_HEIGHT];
qbyte deluxmaps[4*LMBLOCK_WIDTH*LMBLOCK_HEIGHT]; //fixme: make seperate structure for easy disabling with less memory usage.
stmap stainmaps[3*LMBLOCK_WIDTH*LMBLOCK_HEIGHT]; //rgb no a. added to lightmap for added (hopefully) speed.
} lightmapinfo_t;
#endif
extern LPDIRECTDRAWSURFACE7 *lightmap_d3dtextures;
extern LPDIRECTDRAWSURFACE7 *deluxmap_d3dtextures;
extern lightmapinfo_t **lightmap;
extern void *d3dexplosiontexture;
extern void *d3dballtexture;

1263
engine/d3d/vid_d3d.c Normal file

File diff suppressed because it is too large Load diff

821
engine/d3d9/d3d9_draw.c Normal file
View file

@ -0,0 +1,821 @@
#include "quakedef.h"
#ifdef D3DQUAKE
#include "d3d9quake.h"
#define MAX_WIDTH 512
#define MAX_HEIGHT 512
void *d3dexplosiontexture;
void *d3dballtexture;
LPDIRECT3DBASETEXTURE9 d3d9chars_tex;
mpic_t *conback_tex;
typedef struct d3dcachepic_s
{
char name[MAX_QPATH];
mpic_t pic;
} d3dcachepic_t;
#define MAX_CACHED_PICS 512 //a temporary solution
d3dcachepic_t d3dmenu_cachepics[MAX_CACHED_PICS];
int d3dmenu_numcachepics;
typedef struct {
float x, y, z;
int colour;
float s, t;
} d3dquadvert_t;
d3dquadvert_t d3d9quadvert[4];
index_t d3d9quadindexes[6] = {
0, 1, 2,
0, 2, 3
};
//pD3DDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX2, d3dstate.vertbuf, d3dstate.numverts, d3dstate.indexbuf, d3dstate.numindicies, 0);
static void Upload_Texture_32(LPDIRECT3DTEXTURE9 surf, unsigned int *data, int width, int height)
{
int x, y;
unsigned int *dest;
unsigned char swapbuf[4];
unsigned char swapbuf2[4];
D3DLOCKED_RECT lock;
D3DSURFACE_DESC desc;
IDirect3DTexture9_GetLevelDesc(surf, 0, &desc);
IDirect3DTexture9_LockRect(surf, 0, &lock, NULL, DDLOCK_NOSYSLOCK|D3DLOCK_READONLY);
//(surf, NULL, &desc, DDLOCK_NOSYSLOCK|DDLOCK_WAIT|DDLOCK_WRITEONLY|DDLOCK_DISCARDCONTENTS, NULL);
if (width == desc.Width && height == desc.Height)
{
// if (desc.lPitch == twidth*4)
// {
// memcpy(desc.lpSurface, data, width*height*4);
// }
// else
{
for (y = 0; y < height; y++)
{
dest = (unsigned int *)((char *)lock.pBits + lock.Pitch*y);
for (x = 0; x < width; x++)
{
*(unsigned int*)swapbuf2 = *(unsigned int*)swapbuf = data[x];
swapbuf[0] = swapbuf2[2];
swapbuf[2] = swapbuf2[0];
dest[x] = *(unsigned int*)swapbuf;
}
data += width;
}
}
}
else
{
int x, y;
int iny;
unsigned int *row, *inrow;
for (y = 0; y < desc.Height; y++)
{
row = (unsigned int*)((char *)lock.pBits + lock.Pitch*y);
iny = (y * height) / desc.Height;
inrow = data + width*iny;
for (x = 0; x < desc.Width; x++)
{
*(unsigned int*)swapbuf2 = *(unsigned int*)swapbuf = inrow[(x * width)/desc.Width];
swapbuf[0] = swapbuf2[2];
swapbuf[2] = swapbuf2[0];
row[x] = *(unsigned int*)swapbuf;
}
}
//mimic opengl and draw it white
// memset(desc.lpSurface, 255, twidth*theight*4);
}
IDirect3DTexture9_UnlockRect(surf, 0);
}
void D3D9_MipMap (qbyte *out, qbyte *in, int width, int height)
{
int i, j;
width <<=2;
height >>= 1;
for (i=0 ; i<height ; i++, in+=width)
{
for (j=0 ; j<width ; j+=8, out+=4, in+=8)
{
out[0] = (in[0] + in[4] + in[width+0] + in[width+4])>>2;
out[1] = (in[1] + in[5] + in[width+1] + in[width+5])>>2;
out[2] = (in[2] + in[6] + in[width+2] + in[width+6])>>2;
out[3] = (in[3] + in[7] + in[width+3] + in[width+7])>>2;
}
}
}
//create a basic shader from a 32bit image
LPDIRECT3DBASETEXTURE9 D3D9_LoadTexture_32(char *name, unsigned int *data, int width, int height, int flags)
{
int nwidth, nheight;
LPDIRECT3DTEXTURE9 newsurf;
/*
if (!(flags & TF_MANDATORY))
{
Con_Printf("Texture upload missing flags\n");
return NULL;
}
*/
nwidth = width;
nheight = height;
GL_RoundDimensions(&nwidth, &nheight, flags & TF_MIPMAP);
IDirect3DDevice9_CreateTexture(pD3DDev9, nwidth, nheight, 0, 0|((flags & TF_MIPMAP)?D3DUSAGE_AUTOGENMIPMAP:0), D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &newsurf, NULL);
if (!newsurf)
return NULL;
Upload_Texture_32(newsurf, data, width, height);
if (flags & TF_MIPMAP)
IDirect3DBaseTexture9_GenerateMipSubLevels(newsurf);
return (LPDIRECT3DBASETEXTURE9)newsurf;
}
//create a basic shader from an 8bit image with 24bit palette
LPDIRECT3DBASETEXTURE9 D3D9_LoadTexture_8_Pal24(char *name, unsigned char *data, int width, int height, int flags, unsigned char *palette, int transparentpix)
{
//just expands it to 32bpp and passes it on
static unsigned char out[MAX_WIDTH*MAX_HEIGHT][4];
int i;
if (!(flags & TF_ALPHA))
transparentpix = 256;
if (width*height > MAX_WIDTH*MAX_HEIGHT)
Sys_Error("GL_Upload8_Pal24: too big");
for (i = width*height; i >= 0 ; i--)
{
out[i][0] = palette[data[i]*3+0];
out[i][1] = palette[data[i]*3+1];
out[i][2] = palette[data[i]*3+2];
out[i][3] = 255*(data[i] != transparentpix);
}
return D3D9_LoadTexture_32(name, (unsigned int*)out, width, height, flags);
}
LPDIRECT3DBASETEXTURE9 D3D9_LoadTexture_8_Pal32(char *name, unsigned char *data, int width, int height, int flags, unsigned char *palette)
{
//just expands it to 32bpp and passes it on
static unsigned char out[MAX_WIDTH*MAX_HEIGHT][4];
int i;
if (width*height > MAX_WIDTH*MAX_HEIGHT)
Sys_Error("GL_Upload8_Pal24: too big");
for (i = width*height; i >= 0 ; i--)
{
out[i][0] = palette[data[i]*4+0];
out[i][1] = palette[data[i]*4+1];
out[i][2] = palette[data[i]*4+2];
out[i][3] = palette[data[i]*4+3];
}
return D3D9_LoadTexture_32(name, (unsigned int*)out, width, height, flags);
}
void D3D9_UnloadTexture(LPDIRECT3DBASETEXTURE9 tex)
{
if (tex)
IDirect3DBaseTexture9_Release(tex);
}
static qbyte exptexture[16][16] =
{
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0},
{0,0,0,1,1,1,1,1,3,1,1,2,1,0,0,0},
{0,0,0,1,1,1,1,4,4,4,5,4,2,1,1,0},
{0,0,1,1,6,5,5,8,6,8,3,6,3,2,1,0},
{0,0,1,5,6,7,5,6,8,8,8,3,3,1,0,0},
{0,0,0,1,6,8,9,9,9,9,4,6,3,1,0,0},
{0,0,2,1,7,7,9,9,9,9,5,3,1,0,0,0},
{0,0,2,4,6,8,9,9,9,9,8,6,1,0,0,0},
{0,0,2,2,3,5,6,8,9,8,8,4,4,1,0,0},
{0,0,1,2,4,1,8,7,8,8,6,5,4,1,0,0},
{0,1,1,1,7,8,1,6,7,5,4,7,1,0,0,0},
{0,1,2,1,1,5,1,3,4,3,1,1,0,0,0,0},
{0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
};
void D3D9_InitParticleTexture (void)
{
#define PARTICLETEXTURESIZE 64
int x,y;
float dx, dy, d;
qbyte data[PARTICLETEXTURESIZE*PARTICLETEXTURESIZE][4];
//Explosion texture
for (x=0 ; x<16 ; x++)
{
for (y=0 ; y<16 ; y++)
{
data[y*16+x][0] = 255;
data[y*16+x][1] = 255;
data[y*16+x][2] = 255;
data[y*16+x][3] = exptexture[x][y]*255/9.0;
}
}
d3dexplosiontexture = D3D9_LoadTexture_32("", (unsigned int*)data, 16, 16, TF_ALPHA|TF_NOTBUMPMAP|TF_NOMIPMAP);
memset(data, 255, sizeof(data));
for (y = 0;y < PARTICLETEXTURESIZE;y++)
{
dy = (y - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f-1);
for (x = 0;x < PARTICLETEXTURESIZE;x++)
{
dx = (x - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f-1);
d = 256 * (1 - (dx*dx+dy*dy));
d = bound(0, d, 255);
data[y*PARTICLETEXTURESIZE+x][3] = (qbyte) d;
}
}
d3dballtexture = D3D9_LoadTexture_32("", (unsigned int*)data, PARTICLETEXTURESIZE, PARTICLETEXTURESIZE, TF_ALPHA|TF_NOTBUMPMAP|TF_NOMIPMAP);
}
mpic_t *D3D9_Draw_SafePicFromWad (char *name)
{
LPDIRECT3DBASETEXTURE9 *p;
d3dcachepic_t *pic;
qpic_t *qpic;
int i;
for (i = 0; i < d3dmenu_numcachepics; i++)
{
if (!strcmp(d3dmenu_cachepics[i].name, name))
return &d3dmenu_cachepics[i].pic;
}
qpic = (qpic_t *)W_SafeGetLumpName (name);
if (qpic)
SwapPic (qpic);
pic = &d3dmenu_cachepics[d3dmenu_numcachepics];
Q_strncpyz (pic->name, name, sizeof(pic->name));
p = (LPDIRECT3DBASETEXTURE9*)&pic->pic.data;
if (!strcmp(name, "conchars"))
{
pic->pic.width = 256;
pic->pic.height = 256;
*p = d3d9chars_tex;
}
else if (qpic)
{
pic->pic.width = qpic->width;
pic->pic.height = qpic->height;
*p = (LPDIRECT3DBASETEXTURE9)Mod_LoadReplacementTexture(pic->name, "wad", false, true, true);
if (!*p)
*p = D3D9_LoadTexture_8_Pal24(name, (unsigned char*)(qpic+1), qpic->width, qpic->height, TF_NOMIPMAP|TF_ALPHA|TF_NOTBUMPMAP, host_basepal, 255);
}
else
{
extern int image_width, image_height;
*p = (LPDIRECT3DBASETEXTURE9)Mod_LoadHiResTexture(pic->name, "wad", false, true, true);
if (!p)
return NULL;
pic->pic.width = image_width;
pic->pic.height = image_height;
}
d3dmenu_numcachepics++;
// Con_Printf("Fixme: D3D9_Draw_SafePicFromWad\n");
return &pic->pic;
}
mpic_t *D3D9_Draw_SafeCachePic (char *path)
{
LPDIRECT3DBASETEXTURE9 *p;
d3dcachepic_t *pic;
qpic_t *qpic;
int i;
for (i = 0; i < d3dmenu_numcachepics; i++)
{
if (!strcmp(d3dmenu_cachepics[i].name, path))
return &d3dmenu_cachepics[i].pic;
}
qpic = (qpic_t *)COM_LoadTempFile (path);
if (qpic)
SwapPic (qpic);
pic = &d3dmenu_cachepics[d3dmenu_numcachepics];
Q_strncpyz (pic->name, path, sizeof(pic->name));
p = (LPDIRECT3DBASETEXTURE9*)&pic->pic.data;
if (qpic)
{
pic->pic.width = qpic->width;
pic->pic.height = qpic->height;
*p = (LPDIRECT3DBASETEXTURE9)Mod_LoadReplacementTexture(pic->name, "gfx", false, true, true);
if (!*p && qpic)
*p = D3D9_LoadTexture_8_Pal24(path, (unsigned char*)(qpic+1), qpic->width, qpic->height, TF_NOMIPMAP|TF_ALPHA|TF_NOTBUMPMAP, host_basepal, 255);
}
else
{
extern int image_width, image_height;
*p = (LPDIRECT3DBASETEXTURE9)Mod_LoadHiResTexture(pic->name, "gfx", false, true, true);
if (!*p)
{
return NULL;
}
pic->pic.width = image_width;
pic->pic.height = image_height;
}
d3dmenu_numcachepics++;
// Con_Printf("Fixme: D3D9_Draw_SafeCachePic\n");
return &pic->pic;
}
mpic_t *D3D9_Draw_CachePic (char *path)
{
mpic_t *pic;
pic = D3D9_Draw_SafeCachePic(path);
if (!pic)
Sys_Error("Couldn't load picture %s", path);
return pic;
}
void D3D9_Draw_ReInit (void)
{
d3dmenu_numcachepics = 0;
draw_chars = W_SafeGetLumpName ("conchars");
d3d9chars_tex = (LPDIRECT3DBASETEXTURE9)Mod_LoadReplacementTexture("conchars", "gfx", false, true, true);
if (!d3d9chars_tex)
{
if (draw_chars)
d3d9chars_tex = D3D9_LoadTexture_8_Pal24("conchars", draw_chars, 128, 128, TF_NOMIPMAP|TF_ALPHA|TF_NOTBUMPMAP, host_basepal, 0);
if (!d3d9chars_tex)
d3d9chars_tex = (LPDIRECT3DBASETEXTURE9)Mod_LoadHiResTexture("gfx/2d/bigchars.tga", NULL, false, true, false); //try q3 path
if (!d3d9chars_tex)
d3d9chars_tex = (LPDIRECT3DBASETEXTURE9)Mod_LoadHiResTexture("pics/conchars.pcx", NULL, false, true, false); //try low res q2 path
}
//now emit the conchars picture as if from a wad.
strcpy(d3dmenu_cachepics[d3dmenu_numcachepics].name, "conchars");
d3dmenu_cachepics[d3dmenu_numcachepics].pic.width = 128;
d3dmenu_cachepics[d3dmenu_numcachepics].pic.height = 128;
*(int *)&d3dmenu_cachepics[d3dmenu_numcachepics].pic.data = (int)d3d9chars_tex;
d3dmenu_numcachepics++;
conback_tex = D3D9_Draw_SafeCachePic("gfx/conback.lmp");
if (!conback_tex)
conback_tex = D3D9_Draw_SafeCachePic("textures/sfx/logo512.jpg"); //try q3 path
if (!conback_tex)
conback_tex = D3D9_Draw_SafeCachePic("pics/conback.pcx");
Plug_DrawReloadImages();
D3D9_InitParticleTexture();
}
void D3D9_Draw_Init (void)
{
D3D9_Draw_ReInit();
}
void D3D9_Draw_Character (int x, int y, unsigned int num)
{
int row;
int col;
float frow, fcol, size;
#define char_instep 0
num &= 255;
if (num == ' ')
return;
row = num>>4;
col = num&15;
frow = row*0.0625+char_instep;
fcol = col*0.0625+char_instep;
size = 0.0625-char_instep*2;
d3d9quadvert[0].x = x;
d3d9quadvert[0].y = y;
d3d9quadvert[0].z = 0;
d3d9quadvert[0].colour = 0xffffffff;
d3d9quadvert[0].s = fcol;
d3d9quadvert[0].t = frow;
d3d9quadvert[1].x = x+8;
d3d9quadvert[1].y = y;
d3d9quadvert[1].z = 0;
d3d9quadvert[1].colour = 0xffffffff;
d3d9quadvert[1].s = fcol+size;
d3d9quadvert[1].t = frow;
d3d9quadvert[2].x = x+8;
d3d9quadvert[2].y = y+8;
d3d9quadvert[2].z = 0;
d3d9quadvert[2].colour = 0xffffffff;
d3d9quadvert[2].s = fcol+size;
d3d9quadvert[2].t = frow+size;
d3d9quadvert[3].x = x;
d3d9quadvert[3].y = y+8;
d3d9quadvert[3].z = 0;
d3d9quadvert[3].colour = 0xffffffff;
d3d9quadvert[3].s = fcol;
d3d9quadvert[3].t = frow+size;
IDirect3DDevice9_SetTexture(pD3DDev9, 0, d3d9chars_tex);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_TEXCOORDINDEX, 0);
IDirect3DDevice9_SetFVF(pD3DDev9, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1);
IDirect3DDevice9_DrawIndexedPrimitiveUP(pD3DDev9, D3DPT_TRIANGLELIST, 0, 4, 2, d3d9quadindexes, D3DFMT_QINDEX, d3d9quadvert, sizeof(d3d9quadvert[0]));
}
void D3D9_Draw_ColouredCharacter (int x, int y, unsigned int num)
{
int row;
int col;
float frow, fcol, size;
unsigned int imgcolour;
unsigned char *c = (unsigned char *)&imgcolour;
#define char_instep 0
if (num&0xffff == ' ')
return;
col = (num & CON_FGMASK) >> CON_FGSHIFT;
c[0] = consolecolours[col].fb*255;
c[1] = consolecolours[col].fg*255;
c[2] = consolecolours[col].fr*255;
c[3] = (num & CON_HALFALPHA)?128:255;
num &= 0xff;
row = num>>4;
col = num&15;
frow = row*0.0625+char_instep;
fcol = col*0.0625+char_instep;
size = 0.0625-char_instep*2;
d3d9quadvert[0].x = x;
d3d9quadvert[0].y = y;
d3d9quadvert[0].z = 0;
d3d9quadvert[0].colour = imgcolour;
d3d9quadvert[0].s = fcol;
d3d9quadvert[0].t = frow;
d3d9quadvert[1].x = x+8;
d3d9quadvert[1].y = y;
d3d9quadvert[1].z = 0;
d3d9quadvert[1].colour = imgcolour;
d3d9quadvert[1].s = fcol+size;
d3d9quadvert[1].t = frow;
d3d9quadvert[2].x = x+8;
d3d9quadvert[2].y = y+8;
d3d9quadvert[2].z = 0;
d3d9quadvert[2].colour = imgcolour;
d3d9quadvert[2].s = fcol+size;
d3d9quadvert[2].t = frow+size;
d3d9quadvert[3].x = x;
d3d9quadvert[3].y = y+8;
d3d9quadvert[3].z = 0;
d3d9quadvert[3].colour = imgcolour;
d3d9quadvert[3].s = fcol;
d3d9quadvert[3].t = frow+size;
IDirect3DDevice9_SetTexture(pD3DDev9, 0, d3d9chars_tex);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_TEXCOORDINDEX, 0);
IDirect3DDevice9_SetFVF(pD3DDev9, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1);
IDirect3DDevice9_DrawIndexedPrimitiveUP(pD3DDev9, D3DPT_TRIANGLELIST, 0, 4, 2, d3d9quadindexes, D3DFMT_QINDEX, d3d9quadvert, sizeof(d3d9quadvert[0]));
}
void D3D9_Draw_String (int x, int y, const qbyte *str)
{
while(*str)
{
D3D9_Draw_Character(x, y, *str++);
x+=8;
}
}
void D3D9_Draw_Alt_String (int x, int y, const qbyte *str)
{
while(*str)
{
D3D9_Draw_Character(x, y, *str++ | 128);
x+=8;
}
}
void D3D9_Draw_Crosshair (void)
{
D3D9_Draw_Character(vid.width/2 - 4, vid.height/2 - 4, '+');
}
void D3D9_Draw_DebugChar (qbyte num)
{
Sys_Error("D3D function not implemented\n");
}
void D3D9_Draw_TransPicTranslate (int x, int y, int w, int h, qbyte *pic, qbyte *translation)
{
// Sys_Error("D3D function not implemented\n");
}
void D3D9_Draw_TileClear (int x, int y, int w, int h)
{
// Sys_Error("D3D function not implemented\n");
}
void D3D9_Draw_Fill_I (int x, int y, int w, int h, unsigned int imgcolour)
{
d3d9quadvert[0].x = x;
d3d9quadvert[0].y = y;
d3d9quadvert[0].z = 0;
d3d9quadvert[0].colour = imgcolour;
d3d9quadvert[0].s = 0;
d3d9quadvert[0].t = 0;
d3d9quadvert[1].x = x+w;
d3d9quadvert[1].y = y;
d3d9quadvert[1].z = 0;
d3d9quadvert[1].colour = imgcolour;
d3d9quadvert[1].s = 0;
d3d9quadvert[1].t = 0;
d3d9quadvert[2].x = x+w;
d3d9quadvert[2].y = y+h;
d3d9quadvert[2].z = 0;
d3d9quadvert[2].colour = imgcolour;
d3d9quadvert[2].s = 0;
d3d9quadvert[2].t = 0;
d3d9quadvert[3].x = x;
d3d9quadvert[3].y = y+h;
d3d9quadvert[3].z = 0;
d3d9quadvert[3].colour = imgcolour;
d3d9quadvert[3].s = 0;
d3d9quadvert[3].t = 0;
IDirect3DDevice9_SetTexture(pD3DDev9, 0, NULL);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHATESTENABLE, FALSE );
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHABLENDENABLE, TRUE );
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
IDirect3DDevice9_SetFVF(pD3DDev9, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1);
IDirect3DDevice9_DrawIndexedPrimitiveUP(pD3DDev9, D3DPT_TRIANGLELIST, 0, 4, 2, d3d9quadindexes, D3DFMT_QINDEX, d3d9quadvert, sizeof(d3d9quadvert[0]));
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHABLENDENABLE, FALSE );
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHATESTENABLE, TRUE );
IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
}
void D3D9_Draw_FillRGB (int x, int y, int w, int h, float r, float g, float b)
{
char colours[4];
colours[0] = b*255;
colours[1] = g*255;
colours[2] = r*255;
colours[3] = 255;
D3D9_Draw_Fill_I(x, y, w, h, *(unsigned int*)colours);
}
void D3D9_Draw_Fill (int x, int y, int w, int h, int c)
{
D3D9_Draw_FillRGB(x, y, w, h, host_basepal[c*3+0]/255.0f, host_basepal[c*3+1]/255.0f, host_basepal[c*3+2]/255.0f);
}
void D3D9_Draw_FadeScreen (void)
{
// Sys_Error("D3D function not implemented\n");
}
void D3D9_Draw_BeginDisc (void)
{
// Sys_Error("D3D function not implemented\n");
}
void D3D9_Draw_EndDisc (void)
{
// Sys_Error("D3D function not implemented\n");
}
static int imgcolour;
void D3D9_Draw_Fill_Colours (int x, int y, int w, int h)
{
D3D9_Draw_Fill_I(x, y, w, h, imgcolour);
}
void D3D9_Draw_Image (float x, float y, float w, float h, float s1, float t1, float s2, float t2, mpic_t *pic)
{
LPDIRECT3DBASETEXTURE9 *p;
if (!conback_tex)
return;
if (!pic)
return;
d3d9quadvert[0].x = x;
d3d9quadvert[0].y = y;
d3d9quadvert[0].z = 0;
d3d9quadvert[0].colour = imgcolour;
d3d9quadvert[0].s = s1;// - 3.0/pic->width;
d3d9quadvert[0].t = t1;
d3d9quadvert[1].x = x+w;
d3d9quadvert[1].y = y;
d3d9quadvert[1].z = 0;
d3d9quadvert[1].colour = imgcolour;
d3d9quadvert[1].s = s2;// - 3.0/pic->width;
d3d9quadvert[1].t = t1;
d3d9quadvert[2].x = x+w;
d3d9quadvert[2].y = y+h;
d3d9quadvert[2].z = 0;
d3d9quadvert[2].colour = imgcolour;
d3d9quadvert[2].s = s2;// - 3.0/pic->width;
d3d9quadvert[2].t = t2;
d3d9quadvert[3].x = x;
d3d9quadvert[3].y = y+h;
d3d9quadvert[3].z = 0;
d3d9quadvert[3].colour = imgcolour;
d3d9quadvert[3].s = s1;// - 3.0/pic->width;
d3d9quadvert[3].t = t2;
p = (LPDIRECT3DBASETEXTURE9*)&pic->data;
IDirect3DDevice9_SetTexture(pD3DDev9, 0, *p);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_TEXCOORDINDEX, 0);
IDirect3DDevice9_SetFVF(pD3DDev9, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1);
IDirect3DDevice9_DrawIndexedPrimitiveUP(pD3DDev9, D3DPT_TRIANGLELIST, 0, 4, 2, d3d9quadindexes, D3DFMT_QINDEX, d3d9quadvert, sizeof(d3d9quadvert[0]));
}
void D3D9_Draw_ScalePic (int x, int y, int width, int height, mpic_t *pic)
{
D3D9_Draw_Image(x, y, width, height, 0, 0, 1, 1, pic);
}
void D3D9_Draw_SubPic (int x, int y, mpic_t *pic, int srcx, int srcy, int width, int height)
{
float s, t;
float sw, tw;
if (!pic)
return;
s = (float)srcx/pic->width;
t = (float)srcy/pic->height;
sw = (float)width/pic->width;
tw = (float)height/pic->height;
D3D9_Draw_Image(x, y, width, height, s, t, s+sw, t+tw, pic);
}
void D3D9_Draw_TransPic (int x, int y, mpic_t *pic)
{
if (!pic)
return;
D3D9_Draw_Image(x, y, pic->width, pic->height, 0, 0, 1, 1, pic);
}
void D3D9_Draw_Pic (int x, int y, mpic_t *pic)
{
if (!pic)
return;
D3D9_Draw_Image(x, y, pic->width, pic->height, 0, 0, 1, 1, pic);
}
void D3D9_Draw_ImageColours (float r, float g, float b, float a)
{
unsigned char *c = (unsigned char *)&imgcolour;
c[0] = b*255;
c[1] = g*255;
c[2] = r*255;
c[3] = a*255;
}
void D3D9_Draw_ConsoleBackground (int lines)
{
D3D9_Draw_ImageColours(1,1,1,1);
D3D9_Draw_Image(0, 0, vid.width, lines, 0, 1 - (float)lines/vid.height, 1, 1, conback_tex);
}
void D3D9_Draw_EditorBackground (int lines)
{
D3D9_Draw_ConsoleBackground(lines);
}
void D3D9_Media_ShowFrameBGR_24_Flip (qbyte *framedata, int inwidth, int inheight)
{
mpic_t pic;
LPDIRECT3DBASETEXTURE9 *p;
p = (LPDIRECT3DBASETEXTURE9*)&pic.data;
*p = D3D9_LoadTexture_32("", (unsigned int*)framedata, inwidth, inheight, TF_NOMIPMAP|TF_NOALPHA|TF_NOTBUMPMAP);
D3D9_Set2D ();
D3D9_Draw_ImageColours(1,1,1,1);
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHATESTENABLE, FALSE );
D3D9_Draw_Image(0, 0, vid.width, vid.height, 0, 1, 1, 0, &pic);
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHATESTENABLE, TRUE );
D3D9_UnloadTexture(*p);
} //input is bottom up...
void D3D9_Media_ShowFrameRGBA_32 (qbyte *framedata, int inwidth, int inheight)
{
mpic_t pic;
LPDIRECT3DBASETEXTURE9 *p;
pic.width = inwidth;
pic.height = inheight;
pic.flags = 0;
p = (LPDIRECT3DBASETEXTURE9*)&pic.data;
*p = D3D9_LoadTexture_32("", (unsigned int*)framedata, inwidth, inheight, TF_NOMIPMAP|TF_NOALPHA|TF_NOTBUMPMAP);
D3D9_Set2D ();
D3D9_Draw_ImageColours(1,1,1,1);
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHATESTENABLE, FALSE );
D3D9_Draw_Image(0, 0, vid.width, vid.height, 0, 0, 1, 1, &pic);
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHATESTENABLE, TRUE );
D3D9_UnloadTexture(*p);
} //top down
void (D3D9_Media_ShowFrame8bit) (qbyte *framedata, int inwidth, int inheight, qbyte *palette)
{
mpic_t pic;
LPDIRECT3DBASETEXTURE9 *p;
p = (LPDIRECT3DBASETEXTURE9*)&pic.data;
*p = D3D9_LoadTexture_8_Pal24("", (unsigned char*)framedata, inwidth, inheight, TF_NOMIPMAP|TF_NOALPHA|TF_NOTBUMPMAP, palette, 256);
D3D9_Set2D ();
D3D9_Draw_ImageColours(1,1,1,1);
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHATESTENABLE, FALSE );
D3D9_Draw_Image(0, 0, vid.width, vid.height, 0, 0, 1, 1, &pic);
IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHATESTENABLE, TRUE );
D3D9_UnloadTexture(*p);
} //paletted topdown (framedata is 8bit indexes into palette)
#endif

706
engine/d3d9/d3d9_mesh.c Normal file
View file

@ -0,0 +1,706 @@
#include "quakedef.h"
#ifdef D3DQUAKE
#include "d3d9quake.h"
#include "com_mesh.h"
extern cvar_t r_fullbrightSkins;
extern cvar_t r_vertexdlights;
typedef struct {
float x, y, z;
float s, t;
} meshvert_t;
typedef struct {
float x, y, z;
unsigned int colour;
float s, t;
} meshcolouredvert_t;
void D3D9_DrawMesh(mesh_t *mesh)
{
IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG2, D3DTA_CURRENT);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
{
int v;
vec3_t *xyz;
byte_vec4_t *colour;
vec2_t *wm;
xyz = mesh->xyz_array;
wm = mesh->st_array;
colour = mesh->colors_array;
if (colour)
{
meshcolouredvert_t *meshvert = alloca(sizeof(meshcolouredvert_t)*mesh->numvertexes);
for (v = 0; v < mesh->numvertexes; v++, xyz++, wm++, colour++)
{
meshvert[v].x = (*xyz)[0];
meshvert[v].y = (*xyz)[1];
meshvert[v].z = (*xyz)[2];
meshvert[v].colour = *(unsigned int*)colour;
meshvert[v].s = (*wm)[0];
meshvert[v].t = (*wm)[1];
}
IDirect3DDevice9_SetFVF(pD3DDev9, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1);
IDirect3DDevice9_DrawIndexedPrimitiveUP(pD3DDev9, D3DPT_TRIANGLELIST, 0, mesh->numvertexes, mesh->numindexes/3, mesh->indexes, D3DFMT_QINDEX, meshvert, sizeof(meshvert[0]));
}
else
{
meshvert_t *meshvert = alloca(sizeof(meshvert_t)*mesh->numvertexes);
for (v = 0; v < mesh->numvertexes; v++, xyz++, wm++)
{
meshvert[v].x = (*xyz)[0];
meshvert[v].y = (*xyz)[1];
meshvert[v].z = (*xyz)[2];
meshvert[v].s = (*wm)[0];
meshvert[v].t = (*wm)[1];
}
IDirect3DDevice9_SetFVF(pD3DDev9, D3DFVF_XYZ|D3DFVF_TEX1);
IDirect3DDevice9_DrawIndexedPrimitiveUP(pD3DDev9, D3DPT_TRIANGLELIST, 0, mesh->numvertexes, mesh->numindexes/3, mesh->indexes, D3DFMT_QINDEX, meshvert, sizeof(meshvert[0]));
}
}
}
hashtable_t skincolourmapped;
void d3d9_GAliasFlushSkinCache(void)
{
int i;
bucket_t *b;
for (i = 0; i < skincolourmapped.numbuckets; i++)
{
while((b = skincolourmapped.bucket[i]))
{
skincolourmapped.bucket[i] = b->next;
BZ_Free(b->data);
}
}
if (skincolourmapped.bucket)
BZ_Free(skincolourmapped.bucket);
skincolourmapped.bucket = NULL;
skincolourmapped.numbuckets = 0;
}
static galiastexnum_t *D3D9_ChooseSkin(galiasinfo_t *inf, char *modelname, int surfnum, entity_t *e)
{
galiasskin_t *skins;
galiastexnum_t *texnums;
int frame;
int tc, bc;
int local;
if (!gl_nocolors.value)
{
if (e->scoreboard)
{
if (!e->scoreboard->skin)
Skin_Find(e->scoreboard);
tc = e->scoreboard->topcolor;
bc = e->scoreboard->bottomcolor;
//colour forcing
if (cl.splitclients<2 && !(cl.fpd & FPD_NO_FORCE_COLOR)) //no colour/skin forcing in splitscreen.
{
if (cl.teamplay && cl.spectator)
{
local = Cam_TrackNum(0);
if (local < 0)
local = cl.playernum[0];
}
else
local = cl.playernum[0];
if (cl.teamplay && !strcmp(e->scoreboard->team, cl.players[local].team))
{
if (cl_teamtopcolor>=0)
tc = cl_teamtopcolor;
if (cl_teambottomcolor>=0)
bc = cl_teambottomcolor;
}
else
{
if (cl_enemytopcolor>=0)
tc = cl_enemytopcolor;
if (cl_enemybottomcolor>=0)
bc = cl_enemybottomcolor;
}
}
}
else
{
tc = 1;
bc = 1;
}
if (tc != 1 || bc != 1 || (e->scoreboard && e->scoreboard->skin))
{
int inwidth, inheight;
int tinwidth, tinheight;
char *skinname;
qbyte *original;
int cc;
galiascolourmapped_t *cm;
char hashname[512];
cc = (tc<<4)|bc;
if (e->scoreboard && e->scoreboard->skin && !gl_nocolors.value)
{
snprintf(hashname, sizeof(hashname), "%s$%s$%i", modelname, e->scoreboard->skin->name, surfnum);
skinname = hashname;
}
else if (surfnum)
{
snprintf(hashname, sizeof(hashname), "%s$%i", modelname, surfnum);
skinname = hashname;
}
else
skinname = modelname;
if (!skincolourmapped.numbuckets)
Hash_InitTable(&skincolourmapped, 256, BZ_Malloc(Hash_BytesForBuckets(256)));
for (cm = Hash_Get(&skincolourmapped, skinname); cm; cm = Hash_GetNext(&skincolourmapped, skinname, cm))
{
if (cm->colour == cc && cm->skinnum == e->skinnum)
{
return &cm->texnum;
}
}
if (!inf->numskins)
{
skins = NULL;
texnums = NULL;
}
else
{
skins = (galiasskin_t*)((char *)inf + inf->ofsskins);
if (!skins->texnums)
{
skins = NULL;
texnums = NULL;
}
else
{
if (e->skinnum >= 0 && e->skinnum < inf->numskins)
skins += e->skinnum;
texnums = (galiastexnum_t*)((char *)skins + skins->ofstexnums);
}
}
//colourmap isn't present yet.
cm = BZ_Malloc(sizeof(*cm));
Q_strncpyz(cm->name, skinname, sizeof(cm->name));
Hash_Add(&skincolourmapped, cm->name, cm, &cm->bucket);
cm->colour = cc;
cm->skinnum = e->skinnum;
cm->texnum.fullbright = 0;
cm->texnum.base = 0;
if (!texnums)
{ //load just the skin (q2)
/* if (e->scoreboard && e->scoreboard->skin)
{
if (cls.protocol == CP_QUAKE2)
{
original = Skin_Cache32(e->scoreboard->skin);
if (original)
{
inwidth = e->scoreboard->skin->width;
inheight = e->scoreboard->skin->height;
cm->texnum.base = cm->texnum.fullbright = GL_LoadTexture32(e->scoreboard->skin->name, inwidth, inheight, (unsigned int*)original, true, false);
return &cm->texnum;
}
}
else
{
original = Skin_Cache8(e->scoreboard->skin);
if (original)
{
inwidth = e->scoreboard->skin->width;
inheight = e->scoreboard->skin->height;
cm->texnum.base = cm->texnum.fullbright = GL_LoadTexture(e->scoreboard->skin->name, inwidth, inheight, original, true, false);
return &cm->texnum;
}
}
cm->texnum.base = Mod_LoadHiResTexture(e->scoreboard->skin->name, "skins", true, false, true);
return &cm->texnum;
}
*/
return NULL;
}
cm->texnum.bump = texnums[cm->skinnum].bump; //can't colour bumpmapping
if (cls.protocol != CP_QUAKE2 && ((!texnums || !strcmp(modelname, "progs/player.mdl")) && e->scoreboard && e->scoreboard->skin))
{
original = Skin_Cache8(e->scoreboard->skin);
inwidth = e->scoreboard->skin->width;
inheight = e->scoreboard->skin->height;
}
else
{
original = NULL;
inwidth = 0;
inheight = 0;
}
if (!original)
{
if (skins->ofstexels)
{
original = (qbyte *)skins + skins->ofstexels;
inwidth = skins->skinwidth;
inheight = skins->skinheight;
}
else
{
original = NULL;
inwidth = 0;
inheight = 0;
}
}
tinwidth = skins->skinwidth;
tinheight = skins->skinheight;
if (original)
{
int i, j;
qbyte translate[256];
unsigned translate32[256];
static unsigned pixels[512*512];
unsigned *out;
unsigned frac, fracstep;
unsigned scaled_width, scaled_height;
qbyte *inrow;
texnums = &cm->texnum;
texnums->base = 0;
texnums->fullbright = 0;
if (gl_max_size.value <= 0)
gl_max_size.value = 512;
scaled_width = gl_max_size.value < 512 ? gl_max_size.value : 512;
scaled_height = gl_max_size.value < 512 ? gl_max_size.value : 512;
for (i=0 ; i<256 ; i++)
translate[i] = i;
tc<<=4;
bc<<=4;
for (i=0 ; i<16 ; i++)
{
if (tc < 128) // the artists made some backwards ranges. sigh.
translate[TOP_RANGE+i] = tc+i;
else
translate[TOP_RANGE+i] = tc+15-i;
if (bc < 128)
translate[BOTTOM_RANGE+i] = bc+i;
else
translate[BOTTOM_RANGE+i] = bc+15-i;
}
for (i=0 ; i<256 ; i++)
translate32[i] = d_8to24rgbtable[translate[i]];
out = pixels;
fracstep = tinwidth*0x10000/scaled_width;
for (i=0 ; i<scaled_height ; i++, out += scaled_width)
{
inrow = original + inwidth*(i*inheight/scaled_height);
frac = fracstep >> 1;
for (j=0 ; j<scaled_width ; j+=4)
{
out[j] = translate32[inrow[frac>>16]] | 0xff000000;
frac += fracstep;
out[j+1] = translate32[inrow[frac>>16]] | 0xff000000;
frac += fracstep;
out[j+2] = translate32[inrow[frac>>16]] | 0xff000000;
frac += fracstep;
out[j+3] = translate32[inrow[frac>>16]] | 0xff000000;
frac += fracstep;
}
}
texnums->base = D3D9_LoadTexture_32 ("", pixels, scaled_width, scaled_height, TF_NOTBUMPMAP);
/* texnums->base = texture_extension_number++;
GL_Bind(texnums->base);
qglTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
*/
//now do the fullbrights.
out = pixels;
fracstep = tinwidth*0x10000/scaled_width;
for (i=0 ; i<scaled_height ; i++, out += scaled_width)
{
inrow = original + inwidth*(i*inheight/scaled_height);
frac = fracstep >> 1;
for (j=0 ; j<scaled_width ; j+=1)
{
if (inrow[frac>>16] < 255-vid.fullbright)
((char *) (&out[j]))[3] = 0; //alpha 0
frac += fracstep;
}
}
/* texnums->fullbright = texture_extension_number++;
GL_Bind(texnums->fullbright);
qglTexImage2D (GL_TEXTURE_2D, 0, gl_alpha_format, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
*/
}
else
{
skins = (galiasskin_t*)((char *)inf + inf->ofsskins);
if (e->skinnum >= 0 && e->skinnum < inf->numskins)
skins += e->skinnum;
if (!inf->numskins || !skins->texnums)
return NULL;
frame = cl.time*skins->skinspeed;
frame = frame%skins->texnums;
texnums = (galiastexnum_t*)((char *)skins + skins->ofstexnums + frame*sizeof(galiastexnum_t));
memcpy(&cm->texnum, texnums, sizeof(cm->texnum));
}
return &cm->texnum;
}
}
if (!inf->numskins)
return NULL;
skins = (galiasskin_t*)((char *)inf + inf->ofsskins);
if (e->skinnum >= 0 && e->skinnum < inf->numskins)
skins += e->skinnum;
else
{
Con_DPrintf("Skin number out of range\n");
if (!inf->numskins)
return NULL;
}
if (!skins->texnums)
return NULL;
frame = cl.time*skins->skinspeed;
frame = frame%skins->texnums;
texnums = (galiastexnum_t*)((char *)skins + skins->ofstexnums + frame*sizeof(galiastexnum_t));
return texnums;
}
extern vec3_t shadevector;
extern vec3_t ambientlight;
extern vec3_t shadelight;
static void LotsOfLightDirectionHacks(entity_t *e, model_t *m, vec3_t lightaxis[3])
{
int i;
vec3_t dist;
float add;
qboolean nolightdir;
vec3_t lightdir;
if (!(r_refdef.flags & Q2RDF_NOWORLDMODEL))
{
if (e->flags & Q2RF_WEAPONMODEL)
cl.worldmodel->funcs.LightPointValues(cl.worldmodel, r_refdef.vieworg, shadelight, ambientlight, lightdir);
else
cl.worldmodel->funcs.LightPointValues(cl.worldmodel, e->origin, shadelight, ambientlight, lightdir);
}
else
{
ambientlight[0] = ambientlight[1] = ambientlight[2] = shadelight[0] = shadelight[1] = shadelight[2] = 255;
lightdir[0] = 0;
lightdir[1] = 1;
lightdir[2] = 1;
}
if (!r_vertexdlights.value)
{
for (i=0 ; i<dlights_running ; i++)
{
if (cl_dlights[i].radius)
{
VectorSubtract (e->origin,
cl_dlights[i].origin,
dist);
add = cl_dlights[i].radius - Length(dist);
if (add > 0) {
add*=5;
ambientlight[0] += add * cl_dlights[i].color[0];
ambientlight[1] += add * cl_dlights[i].color[1];
ambientlight[2] += add * cl_dlights[i].color[2];
//ZOID models should be affected by dlights as well
shadelight[0] += add * cl_dlights[i].color[0];
shadelight[1] += add * cl_dlights[i].color[1];
shadelight[2] += add * cl_dlights[i].color[2];
}
}
}
}
else
{
}
for (i = 0; i < 3; i++) //clamp light so it doesn't get vulgar.
{
if (ambientlight[i] > 128)
ambientlight[i] = 128;
if (ambientlight[i] + shadelight[i] > 192)
shadelight[i] = 192 - ambientlight[i];
}
if (e->flags & Q2RF_WEAPONMODEL)
{
for (i = 0; i < 3; i++)
{
if (ambientlight[i] < 24)
ambientlight[i] = shadelight[i] = 24;
}
}
//MORE HUGE HACKS! WHEN WILL THEY CEASE!
// clamp lighting so it doesn't overbright as much
// ZOID: never allow players to go totally black
nolightdir = false;
if (m->engineflags & MDLF_PLAYER)
{
float fb = r_fullbrightSkins.value;
if (fb > cls.allow_fbskins)
fb = cls.allow_fbskins;
if (fb < 0)
fb = 0;
if (fb)
{
extern cvar_t r_fb_models;
if (fb >= 1 && r_fb_models.value)
{
ambientlight[0] = ambientlight[1] = ambientlight[2] = 4096;
shadelight[0] = shadelight[1] = shadelight[2] = 4096;
nolightdir = true;
}
else
{
for (i = 0; i < 3; i++)
{
ambientlight[i] = max(ambientlight[i], 8 + fb * 120);
shadelight[i] = max(shadelight[i], 8 + fb * 120);
}
}
}
for (i = 0; i < 3; i++)
{
if (ambientlight[i] < 8)
ambientlight[i] = shadelight[i] = 8;
}
}
if (m->engineflags & MDLF_FLAME)
{
shadelight[0] = shadelight[1] = shadelight[2] = 4096;
ambientlight[0] = ambientlight[1] = ambientlight[2] = 4096;
nolightdir = true;
}
else
{
for (i = 0; i < 3; i++)
{
if (ambientlight[i] > 128)
ambientlight[i] = 128;
shadelight[i] /= 200.0/255;
ambientlight[i] /= 200.0/255;
}
}
if ((e->drawflags & MLS_MASKIN) == MLS_ABSLIGHT)
{
shadelight[0] = shadelight[1] = shadelight[2] = e->abslight;
ambientlight[0] = ambientlight[1] = ambientlight[2] = 0;
}
if ((e->drawflags & MLS_MASKIN) == MLS_FULLBRIGHT || (e->flags & Q2RF_FULLBRIGHT))
{
shadelight[0] = shadelight[1] = shadelight[2] = 255;
ambientlight[0] = ambientlight[1] = ambientlight[2] = 0;
nolightdir = true;
}
//#define SHOWLIGHTDIR
{ //lightdir is absolute, shadevector is relative
shadevector[0] = DotProduct(lightdir, e->axis[0]);
shadevector[1] = DotProduct(lightdir, e->axis[1]);
shadevector[2] = DotProduct(lightdir, e->axis[2]);
if (e->flags & Q2RF_WEAPONMODEL)
{
vec3_t temp;
temp[0] = DotProduct(shadevector, vpn);
temp[1] = DotProduct(shadevector, vright);
temp[2] = DotProduct(shadevector, vup);
VectorCopy(temp, shadevector);
}
VectorNormalize(shadevector);
VectorCopy(shadevector, lightaxis[2]);
VectorVectors(lightaxis[2], lightaxis[1], lightaxis[0]);
VectorInverse(lightaxis[1]);
}
if (e->flags & Q2RF_GLOW)
{
shadelight[0] += sin(cl.time)*0.25;
shadelight[1] += sin(cl.time)*0.25;
shadelight[2] += sin(cl.time)*0.25;
}
//d3d is bgra
//ogl is rgba
//so switch em and use the gl code
add = shadelight[0];
shadelight[0] = shadelight[2];
shadelight[2] = add;
add = ambientlight[0];
ambientlight[0] = ambientlight[2];
ambientlight[2] = add;
}
qboolean R_GAliasBuildMesh(mesh_t *mesh, galiasinfo_t *inf, int frame1, int frame2, float lerp, float alpha, float fg1time, float fg2time, qboolean nolightdir);
//draws currententity
void D3D9_DrawAliasModel(void)
{
mesh_t mesh;
extern entity_t *currententity;
entity_t *e = currententity;
galiasinfo_t *inf;
model_t *m;
galiastexnum_t *skin;
int i;
if (r_secondaryview && e->flags & Q2RF_WEAPONMODEL)
return;
{
extern int cl_playerindex;
if (e->scoreboard && e->model == cl.model_precache[cl_playerindex])
{
m = e->scoreboard->model;
if (!m || m->type != mod_alias)
m = e->model;
}
else
m = e->model;
}
if (!(e->flags & Q2RF_WEAPONMODEL))
if (R_CullEntityBox (e, m->mins, m->maxs))
return;
inf = GLMod_Extradata (m);
if (!inf)
return;
LotsOfLightDirectionHacks(e, m, mesh.lightaxis);
{
float matrix[16];
if (e->flags & Q2RF_WEAPONMODEL && r_refdef.currentplayernum>=0)
{ //view weapons need to be rotated onto the screen first
float view[16];
float ent[16];
Matrix4_ModelMatrixFromAxis(view, cl.viewent[r_refdef.currentplayernum].axis[0], cl.viewent[r_refdef.currentplayernum].axis[1], cl.viewent[r_refdef.currentplayernum].axis[2], cl.viewent[r_refdef.currentplayernum].origin);
Matrix4_ModelMatrixFromAxis(ent, e->axis[0], e->axis[1], e->axis[2], e->origin);
Matrix4_Multiply(view, ent, matrix);
}
else
{
Matrix4_ModelMatrixFromAxis(matrix, e->axis[0], e->axis[1], e->axis[2], e->origin);
}
IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_WORLD, (D3DMATRIX*)matrix);
}
IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
if (e->flags & Q2RF_DEPTHHACK)
{ //apply the depth hack to stop things from poking into walls.
//(basically moving it closer to the screen)
D3DVIEWPORT9 viewport;
IDirect3DDevice9_GetViewport(pD3DDev9, &viewport);
viewport.MinZ = 0;
viewport.MaxZ = 0.3;
IDirect3DDevice9_SetViewport(pD3DDev9, &viewport);
}
IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
for(i = 0;; i++)
{
R_GAliasBuildMesh(&mesh, inf, e->frame, e->oldframe, e->lerpfrac, e->shaderRGBAf[3], e->frame1time, e->frame2time, 0);
skin = D3D9_ChooseSkin(inf, m->name, e->skinnum, e);
if (!skin)
IDirect3DDevice9_SetTexture(pD3DDev9, 0, NULL);
else
IDirect3DDevice9_SetTexture(pD3DDev9, 0, skin->base);
D3D9_DrawMesh(&mesh);
if (inf->nextsurf == 0)
break;
inf = (galiasinfo_t*)((char*)inf + inf->nextsurf);
}
IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
if (e->flags & Q2RF_DEPTHHACK)
{
D3DVIEWPORT9 viewport;
IDirect3DDevice9_GetViewport(pD3DDev9, &viewport);
viewport.MinZ = 0;
viewport.MaxZ = 1;
IDirect3DDevice9_SetViewport(pD3DDev9, &viewport);
}
{
float matrix[16];
Matrix4_Identity(matrix);
IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_WORLD, (D3DMATRIX*)matrix);
}
}
#endif

1874
engine/d3d9/d3d9_rmain.c Normal file

File diff suppressed because it is too large Load diff

1410
engine/d3d9/d3d9_rsurf.c Normal file

File diff suppressed because it is too large Load diff

65
engine/d3d9/d3d9quake.h Normal file
View file

@ -0,0 +1,65 @@
//#include "ddraw.h"
#include "d3d9.h"
LPDIRECT3DBASETEXTURE9 D3D9_LoadTexture_32(char *name, unsigned int *data, int width, int height, int flags);
LPDIRECT3DBASETEXTURE9 D3D9_LoadTexture_8_Pal24(char *name, unsigned char *data, int width, int height, int flags, unsigned char *palette, int transparentpix);
#define D3D9_LoadTexture8Pal32(skinname,width,height,data,palette,usemips,alpha) (int)D3D9_LoadTexture_8_Pal32(skinname, data, width, height, (usemips?TF_MIPMAP:TF_NOMIPMAP) | (alpha?TF_ALPHA:TF_NOALPHA) | TF_NOTBUMPMAP, host_basepal)
#define D3D9_LoadTexture(skinname,width,height,data,usemips,alpha) (int)D3D9_LoadTexture_8_Pal24(skinname, data, width, height, (usemips?TF_MIPMAP:TF_NOMIPMAP) | (alpha?TF_ALPHA:TF_NOALPHA) | TF_NOTBUMPMAP, host_basepal, 255)
#define D3D9_LoadTexture32(skinname,width,height,data,usemips,alpha) (int)D3D9_LoadTexture_32(skinname, data, width, height, (usemips?TF_MIPMAP:TF_NOMIPMAP) | (alpha?TF_ALPHA:TF_NOALPHA) | TF_NOTBUMPMAP)
#define D3D9_LoadTextureFB(skinname,width,height,data,usemips,alpha) 0
#define D3D9_LoadTexture8Bump(skinname,width,height,data,usemips,alpha) 0
#define D3D9_FindTexture(name) -1
#define D3D9_LoadCompressed(name) 0
extern LPDIRECT3DDEVICE9 pD3DDev9;
extern int d_lightstylevalue[256]; // 8.8 fraction of base light value
#define lightmap_bytes 4
extern int numlightmaps;
extern mvertex_t *r_pcurrentvertbase;
#ifndef LMBLOCK_WIDTH
#define LMBLOCK_WIDTH 128
#define LMBLOCK_HEIGHT LMBLOCK_WIDTH
typedef struct glRect_s {
unsigned char l,t,w,h;
} glRect_t;
typedef unsigned char stmap;
typedef struct {
qboolean modified;
qboolean deluxmodified;
glRect_t rectchange;
glRect_t deluxrectchange;
int allocated[LMBLOCK_WIDTH];
qbyte lightmaps[4*LMBLOCK_WIDTH*LMBLOCK_HEIGHT];
qbyte deluxmaps[4*LMBLOCK_WIDTH*LMBLOCK_HEIGHT]; //fixme: make seperate structure for easy disabling with less memory usage.
stmap stainmaps[3*LMBLOCK_WIDTH*LMBLOCK_HEIGHT]; //rgb no a. added to lightmap for added (hopefully) speed.
} lightmapinfo_t;
#endif
extern LPDIRECT3DTEXTURE9 *lightmap_d3d9textures;
extern LPDIRECT3DTEXTURE9 *deluxmap_d3d9textures;
extern lightmapinfo_t **lightmap;
extern void *d3dexplosiontexture;
extern void *d3dballtexture;
extern index_t dummyindex;
#if sizeof_index_t == 2
#define D3DFMT_QINDEX D3DFMT_INDEX16
#else
#define D3DFMT_QINDEX D3DFMT_INDEX32
#endif

1536
engine/d3d9/vid_d3d9.c Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -843,7 +843,7 @@ void R_FlushArrays (void)
if ( !r_arrays_locked ) {
R_DrawTriangleStrips ( indexesArray, numIndexes );
} else {
qglDrawElements( GL_TRIANGLES, numIndexes, GL_UNSIGNED_INT, indexesArray );
qglDrawElements( GL_TRIANGLES, numIndexes, GL_INDEX_TYPE, indexesArray );
}
r_numtris += numIndexes / 3;
@ -888,7 +888,7 @@ void R_FlushArraysMtex (void)
if ( !r_arrays_locked ) {
R_DrawTriangleStrips ( indexesArray, numIndexes );
} else {
qglDrawElements( GL_TRIANGLES, numIndexes, GL_UNSIGNED_INT, indexesArray );
qglDrawElements( GL_TRIANGLES, numIndexes, GL_INDEX_TYPE, indexesArray );
}
r_numtris += numIndexes / 3;
@ -1193,7 +1193,7 @@ void RB_CalcEnvironmentTexCoords( float *st )
R_VertexTCBase
==============
*/
void R_VertexTCBase ( int tcgen, int unit )
float *R_VertexTCBase ( int tcgen, int unit )
{
int i;
// vec3_t t, n;
@ -1203,7 +1203,6 @@ void R_VertexTCBase ( int tcgen, int unit )
// mat3_t axis;
outCoords = tUnitCoordsArray[unit][0];
qglTexCoordPointer( 2, GL_FLOAT, 0, outCoords );
if ( tcgen == TC_GEN_BASE )
{
@ -1278,6 +1277,7 @@ void R_VertexTCBase ( int tcgen, int unit )
}
}
return tUnitCoordsArray[unit][0];
}
/*
@ -1331,7 +1331,7 @@ void R_ModifyTextureCoords ( shaderpass_t *pass, int unit )
} else if ( pass->tcgen == TC_GEN_LIGHTMAP ) {
qglTexCoordPointer( 2, GL_FLOAT, 0, lightmapCoordsArray );
} else {
R_VertexTCBase ( pass->tcgen, unit );
qglTexCoordPointer( 2, GL_FLOAT, 0, R_VertexTCBase (pass->tcgen, unit));
}
return;
}

View file

@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//http://www.quakesrc.org/forums/viewtopic.php?t=4340&start=0
#include "quakedef.h"
#ifdef RGLQUAKE
#include "glquake.h"

View file

@ -798,7 +798,7 @@ TRACE(("dbg: GLDraw_ReInit: Allocating upload buffers\n"));
if (!draw_chars) //or low res.
{
if (!(char_texture=Mod_LoadHiResTexture("pics/conchars.pcx", NULL, false, true, false))) //try low res q2 path
if (!(char_texture=Mod_LoadHiResTexture("gfx/2d/bigchars.tga", NULL, false, true, false))) //try low res q2 path
if (!(char_texture=Mod_LoadHiResTexture("gfx/2d/bigchars.tga", NULL, false, true, false))) //try q3 path
{
//gulp... so it's come to this has it? rework the hexen2 conchars into the q1 system.

View file

@ -1,6 +1,9 @@
#include "quakedef.h"
#if defined(TERRAIN) && !defined(SERVERONLY) //fixme
#ifdef RGLQUAKE
#include "glquake.h"
#endif
//heightmaps work thusly:
//there is one raw heightmap file
@ -27,7 +30,7 @@ typedef struct {
unsigned short mins[SECTIONS*SECTIONS], maxs[SECTIONS*SECTIONS];
} heightmap_t;
#ifdef RGLQUAKE
#define DISPLISTS
//#define MULTITEXTURE //ATI suck. I don't know about anyone else (this goes at 1/5th the speed).
@ -51,7 +54,7 @@ void GL_DrawHeightmapModel (entity_t *e)
R_ClearSkyBox();
R_ForceSkyBox();
R_DrawSkyBox(NULL);
GL_DrawSkyBox(NULL);
}
else
qglColor4fv(e->shaderRGBAf);
@ -173,6 +176,8 @@ void GL_DrawHeightmapModel (entity_t *e)
}
}
}
#endif
unsigned int Heightmap_PointContentsHM(heightmap_t *hm, float clipmipsz, vec3_t org)
{
float x, y;
@ -652,6 +657,10 @@ qboolean GL_LoadHeightmapModel (model_t *mod, void *buffer)
Con_Printf(S_ERROR "%s wasn't terrain map\n", mod->name); //shouldn't happen
return false;
}
if (qrenderer != QR_OPENGL)
return false;
for(;;)
{
buffer = COM_Parse(buffer);
@ -751,10 +760,11 @@ qboolean GL_LoadHeightmapModel (model_t *mod, void *buffer)
hm->heightscale = heightsize;
hm->numsegs = numsegs;
hm->detailtexture = Mod_LoadHiResTexture(detailtexname, "", true, true, false);
mod->entities = COM_LoadHunkFile(entfile);
#ifdef RGLQUAKE
hm->detailtexture = Mod_LoadHiResTexture(detailtexname, "", true, true, false);
for (x = 0; x < numsegs; x++)
{
for (y = 0; y < numsegs; y++)
@ -764,6 +774,7 @@ qboolean GL_LoadHeightmapModel (model_t *mod, void *buffer)
qglTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
}
#endif
R_SetSky(skyname, skyrotate, skyaxis);

View file

@ -23,8 +23,17 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// on the same machine.
#include "quakedef.h"
#ifdef RGLQUAKE
#if defined(RGLQUAKE) || defined(D3DQUAKE)
#if defined(RGLQUAKE)
#include "glquake.h"
#endif
#ifdef D3DQUAKE
#include "d3dquake.h"
#endif
#ifdef Q3SHADERS
#include "shader.h"
@ -46,9 +55,8 @@ extern char loadname[32]; // for hunk tags
void CM_Init(void);
qboolean GLMod_LoadCompositeAnim(model_t *mod, void *buffer);
qboolean Mod_LoadCompositeAnim(model_t *mod, void *buffer);
qboolean GL_LoadHeightmapModel (model_t *mod, void *buffer);
qboolean GLMod_LoadDarkPlacesModel(model_t *mod, void *buffer);
qboolean GLMod_LoadSpriteModel (model_t *mod, void *buffer);
qboolean GLMod_LoadSprite2Model (model_t *mod, void *buffer);
qboolean GLMod_LoadBrushModel (model_t *mod, void *buffer);
@ -57,10 +65,11 @@ qboolean Mod_LoadQ2BrushModel (model_t *mod, void *buffer);
#endif
qboolean Mod_LoadHLModel (model_t *mod, void *buffer);
#ifdef ZYMOTICMODELS
qboolean GLMod_LoadZymoticModel(model_t *mod, void *buffer);
qboolean Mod_LoadZymoticModel(model_t *mod, void *buffer);
qboolean Mod_LoadDarkPlacesModel(model_t *mod, void *buffer);
#endif
#ifdef MD5MODELS
qboolean GLMod_LoadMD5MeshModel(model_t *mod, void *buffer);
qboolean Mod_LoadMD5MeshModel(model_t *mod, void *buffer);
#endif
model_t *GLMod_LoadModel (model_t *mod, qboolean crash);
@ -68,12 +77,12 @@ model_t *GLMod_LoadModel (model_t *mod, qboolean crash);
qboolean Mod_LoadDoomLevel(model_t *mod);
#endif
qboolean GL_LoadQ1Model (model_t *mod, void *buffer);
qboolean Mod_LoadQ1Model (model_t *mod, void *buffer);
#ifdef MD2MODELS
qboolean GL_LoadQ2Model (model_t *mod, void *buffer);
qboolean Mod_LoadQ2Model (model_t *mod, void *buffer);
#endif
#ifdef MD3MODELS
qboolean GL_LoadQ3Model (model_t *mod, void *buffer);
qboolean Mod_LoadQ3Model (model_t *mod, void *buffer);
#endif
#ifdef DOOMWADS
@ -187,13 +196,12 @@ void GLMod_BlockTextureColour_f (void)
if (!stricmp(tx->name, match))
{
tx->gl_texturenum = GL_LoadTexture32(texname, 8, 8, colour, true, false);
tx->gl_texturenum = R_LoadTexture32(texname, 8, 8, colour, true, false);
}
}
}
}
}
/*
===============
Mod_Init
@ -455,7 +463,7 @@ model_t *GLMod_LoadModel (model_t *mod, qboolean crash)
//
//look for a replacement, but not for q1 sprites
ext = COM_FileExtension(mod->name);
if (Q_strcasecmp(ext, "spr") && Q_strcasecmp(ext, "sp2"))
if (gl_load24bit.value && Q_strcasecmp(ext, "spr") && Q_strcasecmp(ext, "sp2"))
{
char mdlbase[MAX_QPATH];
COM_StripExtension(mod->name, mdlbase, sizeof(mdlbase));
@ -535,25 +543,47 @@ couldntload:
switch (LittleLong(*(unsigned *)buf))
{
//The binary 3d mesh model formats
case IDPOLYHEADER:
if (!GL_LoadQ1Model(mod, buf))
if (!Mod_LoadQ1Model(mod, buf))
goto couldntload;
break;
#ifdef MD2MODELS
case MD2IDALIASHEADER:
if (!GL_LoadQ2Model(mod, buf))
if (!Mod_LoadQ2Model(mod, buf))
goto couldntload;
break;
#endif
#ifdef MD3MODELS
case MD3_IDENT:
if (!GL_LoadQ3Model (mod, buf))
if (!Mod_LoadQ3Model (mod, buf))
goto couldntload;
break;
#endif
#ifdef HALFLIFEMODELS
case (('T'<<24)+('S'<<16)+('D'<<8)+'I'):
if (!Mod_LoadHLModel (mod, buf))
goto couldntload;
break;
#endif
//Binary skeletal model formats
#ifdef ZYMOTICMODELS
case (('O'<<24)+('M'<<16)+('Y'<<8)+'Z'):
if (!Mod_LoadZymoticModel(mod, buf))
goto couldntload;
break;
case (('K'<<24)+('R'<<16)+('A'<<8)+'D'):
if (!Mod_LoadDarkPlacesModel(mod, buf))
goto couldntload;
break;
#endif
//Binary Sprites
#ifdef SP2MODELS
case IDSPRITE2HEADER:
if (!GLMod_LoadSprite2Model (mod, buf))
@ -565,6 +595,9 @@ couldntload:
if (!GLMod_LoadSpriteModel (mod, buf))
goto couldntload;
break;
//Binary Map formats
#ifdef Q2BSPS
case ('R'<<0)+('B'<<8)+('S'<<16)+('P'<<24):
case IDBSPHEADER: //looks like id switched to have proper ids
@ -572,20 +605,9 @@ couldntload:
goto couldntload;
break;
#endif
#ifdef HALFLIFEMODELS
case (('T'<<24)+('S'<<16)+('D'<<8)+'I'):
if (!Mod_LoadHLModel (mod, buf))
goto couldntload;
break;
#endif
#ifdef TERRAINMAPS
case (('R'<<24)+('R'<<16)+('E'<<8)+'T'):
Mod_LoadTerrain(mod, buf);
break;
#endif
#ifdef DOOMWADS
case (('D'<<24)+('A'<<16)+('W'<<8)+'I'):
case (('D'<<24)+('A'<<16)+('W'<<8)+'P'):
case (('D'<<24)+('A'<<16)+('W'<<8)+'I'): //the id is hacked by the FS .wad loader (main wad).
case (('D'<<24)+('A'<<16)+('W'<<8)+'P'): //the id is hacked by the FS .wad loader (patch wad).
if (!Mod_LoadDoomLevel (mod))
goto couldntload;
break;
@ -597,35 +619,27 @@ couldntload:
if (!GLMod_LoadBrushModel (mod, buf))
goto couldntload;
break;
#ifdef ZYMOTICMODELS
case (('O'<<24)+('M'<<16)+('Y'<<8)+'Z'):
if (!GLMod_LoadZymoticModel(mod, buf))
goto couldntload;
break;
case (('K'<<24)+('R'<<16)+('A'<<8)+'D'):
if (!GLMod_LoadDarkPlacesModel(mod, buf))
goto couldntload;
break;
#endif
//Text based misc types.
default:
//check for text based headers
COM_Parse((char*)buf);
#ifdef MD5MODELS
if (!strcmp(com_token, "MD5Version"))
if (!strcmp(com_token, "MD5Version")) //doom3 format, text based, skeletal
{
if (!GLMod_LoadMD5MeshModel (mod, buf))
if (!Mod_LoadMD5MeshModel (mod, buf))
goto couldntload;
break;
}
if (!strcmp(com_token, "EXTERNALANIM"))
if (!strcmp(com_token, "EXTERNALANIM")) //custom format, text based, specifies skeletal models to load and which md5anim files to use.
{
if (!GLMod_LoadCompositeAnim (mod, buf))
if (!Mod_LoadCompositeAnim (mod, buf))
goto couldntload;
break;
}
#endif
#ifdef TERRAIN
if (!strcmp(com_token, "terrain"))
if (!strcmp(com_token, "terrain")) //custom format, text based.
{
if (!GL_LoadHeightmapModel(mod, buf))
goto couldntload;
@ -812,6 +826,7 @@ void GLMod_LoadAdvancedTextureSection(char *section, char *name, int *base, int
if (!*stdname && !*flatname)
return;
TRACE(("dbg: GLMod_LoadAdvancedTextureSection: %s\n", name));
if (norm && gl_bumpmappingpossible && cls.allow_bump)
{
*base = 0;
@ -935,11 +950,10 @@ TRACE(("dbg: GLMod_LoadTextures: inittexturedescs\n"));
// the pixels immediately follow the structures
// memcpy ( tx+1, mt+1, pixels); //have to be saved for dynamic screen changing (done by reloading entire vid/draw subsystem and all textures)
if (!Q_strncmp(mt->name,"sky",3))
{
tx->offsets[0] = (char *)mt + mt->offsets[0] - (char *)tx;
GLR_InitSky (tx);
R_InitSky (tx);
}
else
#ifdef PEXT_BULLETENS
@ -957,21 +971,17 @@ TRACE(("dbg: GLMod_LoadTextures: inittexturedescs\n"));
{//external textures have already been filtered.
base = W_ConvertWAD3Texture(mt, &mt->width, &mt->height, &alphaed); //convert texture to 32 bit.
tx->alphaed = alphaed;
texture_mode = GL_LINEAR_MIPMAP_NEAREST; //_LINEAR;
if (!(tx->gl_texturenum = Mod_LoadReplacementTexture(mt->name, loadname, true, alphaed, true)))
if (!(tx->gl_texturenum = Mod_LoadReplacementTexture(mt->name, "bmodels", true, alphaed, true)))
tx->gl_texturenum = GL_LoadTexture32 (mt->name, tx->width, tx->height, (unsigned int *)base, true, alphaed);
tx->gl_texturenum = R_LoadTexture32 (mt->name, tx->width, tx->height, (unsigned int *)base, true, alphaed);
*tx->name = *mt->name;
texture_mode = GL_LINEAR;
}
else
{
texture_mode = GL_LINEAR_MIPMAP_NEAREST; //_LINEAR;
if (!(tx->gl_texturenum = Mod_LoadReplacementTexture(mt->name, loadname, true, false, true)))
if (!(tx->gl_texturenum = Mod_LoadReplacementTexture(mt->name, "bmodels", true, false, true)))
tx->gl_texturenum = GL_LoadTexture (mt->name, tx->width, tx->height, base, true, false);
texture_mode = GL_LINEAR;
tx->gl_texturenum = R_LoadTexture8 (mt->name, tx->width, tx->height, base, true, false);
if (r_fb_bmodels.value)
{
@ -983,7 +993,7 @@ TRACE(("dbg: GLMod_LoadTextures: inittexturedescs\n"));
tx->gl_texturenumfb = Mod_LoadReplacementTexture(altname, "bmodels", true, false, true);
}
if (!tx->gl_texturenumfb) //generate one (if possible).
tx->gl_texturenumfb = GL_LoadTextureFB(altname, tx->width, tx->height, base, true, true);
tx->gl_texturenumfb = R_LoadTextureFB(altname, tx->width, tx->height, base, true, true);
}
}
@ -1017,7 +1027,7 @@ TRACE(("dbg: GLMod_LoadTextures: inittexturedescs\n"));
for (j = 0; j < pixels; j++)
base[j] = (host_basepal[base[j]*3] + host_basepal[base[j]*3+1] + host_basepal[base[j]*3+2]) / 3;
tx->gl_texturenumbumpmap = GL_LoadTexture8Bump(altname, tx->width, tx->height, base, true, r_shadow_bumpscale_basetexture.value); //normalise it and then bump it.
tx->gl_texturenumbumpmap = R_LoadTexture8Bump(altname, tx->width, tx->height, base, true, r_shadow_bumpscale_basetexture.value); //normalise it and then bump it.
}
//don't do any complex quake 8bit -> glossmap. It would likly look a little ugly...
@ -1181,7 +1191,6 @@ void GLMod_NowLoadExternal(void)
#endif
{
qbyte * data;
texture_mode = GL_LINEAR_MIPMAP_NEAREST; //_LINEAR;
data = W_GetTexture(tx->name, &width, &height, &alphaed);
if (data)
@ -1192,7 +1201,6 @@ void GLMod_NowLoadExternal(void)
if (!(tx->gl_texturenum = Mod_LoadHiResTexture(tx->name, loadname, true, false, true)))
if (!(tx->gl_texturenum = Mod_LoadHiResTexture(tx->name, "bmodels", true, false, true)))
tx->gl_texturenum = Mod_LoadReplacementTexture("light1_4", NULL, true, false, true); //a fallback. :/
texture_mode = GL_LINEAR;
}
}
if (!tx->gl_texturenumbumpmap && *tx->name != '{' && gl_bumpmappingpossible && cls.allow_bump)
@ -1217,7 +1225,7 @@ void GLMod_NowLoadExternal(void)
*heightmap++ = (data[j*4+0] + data[j*4+1] + data[j*4+2])/3;
}
tx->gl_texturenumbumpmap = GL_LoadTexture8Bump (va("%s_bump", tx->name), width, height, heightmap-j, true, r_shadow_bumpscale_basetexture.value);
tx->gl_texturenumbumpmap = R_LoadTexture8Bump (va("%s_bump", tx->name), width, height, heightmap-j, true, r_shadow_bumpscale_basetexture.value);
}
}
}
@ -2519,6 +2527,7 @@ float RadiusFromBounds (vec3_t mins, vec3_t maxs);
void GLR_StainSurf (msurface_t *surf, float *parms);
static void Q1BSP_StainNode (mnode_t *node, float *parms)
{
#ifdef RGLQUAKE
mplane_t *splitplane;
float dist;
msurface_t *surf;
@ -2552,6 +2561,7 @@ static void Q1BSP_StainNode (mnode_t *node, float *parms)
Q1BSP_StainNode (node->children[0], parms);
Q1BSP_StainNode (node->children[1], parms);
#endif
}
@ -2560,6 +2570,121 @@ qboolean Q1BSP_Trace(model_t *model, int forcehullnum, int frame, vec3_t start,
void GLQ1BSP_LightPointValues(model_t *model, vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir);
void GLMod_FixupNodeMinsMaxs (mnode_t *node, mnode_t *parent)
{
if (!node)
return;
if (node->contents >= 0)
{
GLMod_FixupNodeMinsMaxs (node->children[0], node);
GLMod_FixupNodeMinsMaxs (node->children[1], node);
}
if (parent)
{
if (parent->minmaxs[0] > node->minmaxs[0])
parent->minmaxs[0] = node->minmaxs[0];
if (parent->minmaxs[1] > node->minmaxs[1])
parent->minmaxs[1] = node->minmaxs[1];
if (parent->minmaxs[2] > node->minmaxs[2])
parent->minmaxs[2] = node->minmaxs[2];
if (parent->minmaxs[3] < node->minmaxs[3])
parent->minmaxs[3] = node->minmaxs[3];
if (parent->minmaxs[4] < node->minmaxs[4])
parent->minmaxs[4] = node->minmaxs[4];
if (parent->minmaxs[5] < node->minmaxs[5])
parent->minmaxs[5] = node->minmaxs[5];
}
}
void GLMod_FixupMinsMaxs(void)
{
//q1 bsps are capped to +/- 32767 by the nodes/leafs
//verts arn't though
//so if the map is too big, let's figure out what they should be
float *v;
msurface_t **mark, *surf;
mleaf_t *pleaf;
medge_t *e, *pedges;
int en, lindex;
int i, c, lnumverts;
qboolean needsfixup = false;
if (loadmodel->mins[0] < -32768)
needsfixup = true;
if (loadmodel->mins[1] < -32768)
needsfixup = true;
if (loadmodel->mins[2] < -32768)
needsfixup = true;
if (loadmodel->maxs[0] > 32767)
needsfixup = true;
if (loadmodel->maxs[1] > 32767)
needsfixup = true;
if (loadmodel->maxs[2] > 32767)
needsfixup = true;
if (!needsfixup)
return;
//this is insane.
//why am I writing this?
//by the time the world actually gets this large, the floating point errors are going to be so immensly crazy that it's just not worth it.
pedges = loadmodel->edges;
for (i = 0; i < loadmodel->numleafs; i++)
{
pleaf = &loadmodel->leafs[i];
mark = pleaf->firstmarksurface;
c = pleaf->nummarksurfaces;
if (c)
{
do
{
surf = (*mark++);
lnumverts = surf->numedges;
for (en=0 ; en<lnumverts ; en++)
{
lindex = currentmodel->surfedges[surf->firstedge + en];
if (lindex > 0)
{
e = &pedges[lindex];
v = currentmodel->vertexes[e->v[0]].position;
}
else
{
e = &pedges[-lindex];
v = currentmodel->vertexes[e->v[1]].position;
}
if (pleaf->minmaxs[0] > v[0])
pleaf->minmaxs[0] = v[0];
if (pleaf->minmaxs[1] > v[1])
pleaf->minmaxs[1] = v[1];
if (pleaf->minmaxs[2] > v[2])
pleaf->minmaxs[2] = v[2];
if (pleaf->minmaxs[3] < v[0])
pleaf->minmaxs[3] = v[0];
if (pleaf->minmaxs[4] < v[1])
pleaf->minmaxs[4] = v[1];
if (pleaf->minmaxs[5] < v[2])
pleaf->minmaxs[5] = v[2];
}
} while (--c);
}
}
GLMod_FixupNodeMinsMaxs (loadmodel->nodes, NULL); // sets nodes and leafs
}
/*
=================
Mod_LoadBrushModel
@ -2765,6 +2890,9 @@ qboolean GLMod_LoadBrushModel (model_t *mod, void *buffer)
LightLoadEntities(lightmodel->entities);
#endif
if (1)
GLMod_FixupMinsMaxs();
return true;
}
@ -2925,17 +3053,17 @@ void * GLMod_LoadSpriteFrame (void * pin, mspriteframe_t **ppframe, int framenum
{
size *= 4;
if (!pspriteframe->gl_texturenum)
pspriteframe->gl_texturenum = GL_LoadTexture32 (name, width, height, (unsigned *)(pinframe + 1), true, true);
pspriteframe->gl_texturenum = R_LoadTexture32 (name, width, height, (unsigned *)(pinframe + 1), true, true);
}
else if (version == SPRITEHL_VERSION)
{
if (!pspriteframe->gl_texturenum)
pspriteframe->gl_texturenum = GL_LoadTexture8Pal32 (name, width, height, (qbyte *)(pinframe + 1), (qbyte*)palette, true, true);
pspriteframe->gl_texturenum = R_LoadTexture8Pal32 (name, width, height, (qbyte *)(pinframe + 1), (qbyte*)palette, true, true);
}
else
{
if (!pspriteframe->gl_texturenum)
pspriteframe->gl_texturenum = GL_LoadTexture (name, width, height, (qbyte *)(pinframe + 1), true, true);
pspriteframe->gl_texturenum = R_LoadTexture8 (name, width, height, (qbyte *)(pinframe + 1), true, true);
}
return (void *)((qbyte *)(pinframe+1) + size);
@ -3193,6 +3321,7 @@ qboolean GLMod_LoadSprite2Model (model_t *mod, void *buffer)
frame = psprite->frames[i].frameptr = Hunk_AllocName(sizeof(mspriteframe_t), loadname);
frame->gl_texturenum = Mod_LoadHiResTexture(pframetype->name, NULL, true, true, true);
frame->width = LittleLong(pframetype->width);
frame->height = LittleLong(pframetype->height);
origin[0] = LittleLong (pframetype->origin_x);

View file

@ -56,7 +56,18 @@ typedef struct {
int (*LeafnumForPoint) (struct model_s *model, vec3_t point);
} bspfuncs_t;
typedef int index_t;
#ifdef D3DQUAKE
#define sizeof_index_t 2
#endif
#if sizeof_index_t == 2
#define GL_INDEX_TYPE GL_UNSIGNED_SHORT
typedef unsigned short index_t;
#else
#define GL_INDEX_TYPE GL_UNSIGNED_INT
typedef unsigned int index_t;
#endif
typedef struct mesh_s
{
int numvertexes;
@ -336,9 +347,13 @@ typedef struct mleaf_s
int nummarksurfaces;
int key; // BSP sequence number for leaf's contents
qbyte ambient_sound_level[NUM_AMBIENTS];
#if defined(Q2BSPS) || defined(Q3BSPS)
int cluster;
struct mleaf_s *vischain;
#endif
#ifdef Q2BSPS
//it's a q2 thing
int cluster;
int area;
unsigned short firstleafbrush;
unsigned short numleafbrushes;
@ -348,8 +363,6 @@ typedef struct mleaf_s
unsigned short numleafpatches;
unsigned short firstleafpatch;
struct mleaf_s *vischain;
#endif
} mleaf_t;

View file

@ -141,7 +141,7 @@ typedef struct {
#define MAXARRAYVERTS 2048
static surfvertexarray_t varray_v[MAXARRAYVERTS];
static unsigned int varray_i[MAXARRAYVERTS];
static index_t varray_i[MAXARRAYVERTS];
//static unsigned int varray_i_forward[MAXARRAYVERTS];
//static unsigned int varray_i_polytotri[MAXARRAYVERTS]; //012 023 034 045...
int varray_ic;
@ -162,7 +162,7 @@ inline void PPL_EnableVertexArrays(void)
inline void PPL_FlushArrays(void)
{
if (varray_ic)
qglDrawElements(GL_TRIANGLES, varray_ic, GL_UNSIGNED_INT, varray_i);
qglDrawElements(GL_TRIANGLES, varray_ic, GL_INDEX_TYPE, varray_i);
varray_ic = 0;
varray_vc = 0;
}
@ -362,8 +362,8 @@ static void PPL_BaseChain_NoBump_1TMU(msurface_t *first, texture_t *tex)
qglVertexPointer(3, GL_FLOAT, 0, s->mesh->xyz_array);
qglDrawRangeElements(GL_TRIANGLES, 0, s->mesh->numvertexes, s->mesh->numindexes, GL_UNSIGNED_INT, s->mesh->indexes);
//qglDrawElements(GL_TRIANGLES, s->mesh->numindexes, GL_UNSIGNED_INT, s->mesh->indexes);
qglDrawRangeElements(GL_TRIANGLES, 0, s->mesh->numvertexes, s->mesh->numindexes, GL_INDEX_TYPE, s->mesh->indexes);
//qglDrawElements(GL_TRIANGLES, s->mesh->numindexes, GL_INDEX_TYPE, s->mesh->indexes);
}
qglDisable(GL_TEXTURE_2D);
@ -448,7 +448,7 @@ static void PPL_BaseChain_NoBump_2TMU_Overbright(msurface_t *s, texture_t *tex)
qglVertexPointer(3, GL_FLOAT, 0, s->mesh->xyz_array);
qglDrawRangeElements(GL_TRIANGLES, 0, s->mesh->numvertexes, s->mesh->numindexes, GL_UNSIGNED_INT, s->mesh->indexes);
qglDrawRangeElements(GL_TRIANGLES, 0, s->mesh->numvertexes, s->mesh->numindexes, GL_INDEX_TYPE, s->mesh->indexes);
}
if (overbright != 1)
@ -1146,7 +1146,7 @@ static void PPL_BaseChain_Specular_FP(msurface_t *s, texture_t *tex)
qglTexCoordPointer(2, GL_FLOAT, 0, s->mesh->lmst_array);
qglVertexPointer(3, GL_FLOAT, 0, s->mesh->xyz_array);
qglDrawElements(GL_TRIANGLES, s->mesh->numindexes, GL_UNSIGNED_INT, s->mesh->indexes);
qglDrawElements(GL_TRIANGLES, s->mesh->numindexes, GL_INDEX_TYPE, s->mesh->indexes);
}
GLSlang_UseProgram(0);
@ -1288,7 +1288,7 @@ static void PPL_BaseChain_Flat(msurface_t *first)
qglTexCoordPointer(2, GL_FLOAT, 0, s->mesh->lmst_array);
qglVertexPointer(3, GL_FLOAT, 0, s->mesh->xyz_array);
qglDrawRangeElements(GL_TRIANGLES, 0, s->mesh->numvertexes, s->mesh->numindexes, GL_UNSIGNED_INT, s->mesh->indexes);
qglDrawRangeElements(GL_TRIANGLES, 0, s->mesh->numvertexes, s->mesh->numindexes, GL_INDEX_TYPE, s->mesh->indexes);
}
qglDisableClientState(GL_TEXTURE_COORD_ARRAY);
@ -1654,7 +1654,7 @@ static void PPL_BaseTextureChain(msurface_t *first)
t = GLR_TextureAnimation (first->texinfo->texture);
t = R_TextureAnimation (first->texinfo->texture);
if (first->flags & SURF_DRAWTURB)
{
@ -1714,7 +1714,7 @@ static void PPL_FullBrightTextureChain(msurface_t *first)
texture_t *t;
msurface_t *s;
t = GLR_TextureAnimation (first->texinfo->texture);
t = R_TextureAnimation (first->texinfo->texture);
if (detailtexture && gl_detail.value)
{
@ -1797,7 +1797,7 @@ void PPL_BaseTextures(model_t *model)
if (s)
{
t->texturechain = NULL;
R_DrawSkyChain (s);
GL_DrawSkyChain (s);
}
}
}
@ -2511,7 +2511,7 @@ void PPL_LightTexturesFP_Cached(model_t *model, vec3_t modelorigin, dlight_t *li
s = shm->litsurfs[j].s[0];
t = s->texinfo->texture;
t = GLR_TextureAnimation (t);
t = R_TextureAnimation (t);
for (i=0 ; i<shm->litsurfs[j].count ; i++)
{
@ -2582,7 +2582,7 @@ void PPL_LightTexturesFP_Cached(model_t *model, vec3_t modelorigin, dlight_t *li
qglTexCoordPointer(2, GL_FLOAT, 0, s->mesh->st_array);
qglVertexPointer(3, GL_FLOAT, 0, s->mesh->xyz_array);
qglDrawElements(GL_TRIANGLES, s->mesh->numindexes, GL_UNSIGNED_INT, s->mesh->indexes);
qglDrawElements(GL_TRIANGLES, s->mesh->numindexes, GL_INDEX_TYPE, s->mesh->indexes);
}
}
GLSlang_UseProgram(0);
@ -2628,7 +2628,7 @@ void PPL_LightTexturesFP(model_t *model, vec3_t modelorigin, dlight_t *light, ve
// if ((s->flags & SURF_DRAWTURB) && r_wateralphaval != 1.0)
// continue; // draw translucent water later
t = GLR_TextureAnimation (t);
t = R_TextureAnimation (t);
p = 0;
@ -2684,7 +2684,7 @@ void PPL_LightTexturesFP(model_t *model, vec3_t modelorigin, dlight_t *light, ve
qglTexCoordPointer(2, GL_FLOAT, 0, s->mesh->st_array);
qglVertexPointer(3, GL_FLOAT, 0, s->mesh->xyz_array);
qglDrawElements(GL_TRIANGLES, s->mesh->numindexes, GL_UNSIGNED_INT, s->mesh->indexes);
qglDrawElements(GL_TRIANGLES, s->mesh->numindexes, GL_INDEX_TYPE, s->mesh->indexes);
}
}
@ -2732,7 +2732,7 @@ void PPL_LightTextures(model_t *model, vec3_t modelorigin, dlight_t *light, vec3
{
extern int normalisationCubeMap;
t = GLR_TextureAnimation (t);
t = R_TextureAnimation (t);
qglEnableClientState(GL_COLOR_ARRAY);
@ -2814,7 +2814,7 @@ void PPL_LightTextures(model_t *model, vec3_t modelorigin, dlight_t *light, vec3
PPL_GenerateLightArrays(s, relativelightorigin, light, colour);
qglVertexPointer(3, GL_FLOAT, 0, s->mesh->xyz_array);
qglDrawElements(GL_TRIANGLES, s->mesh->numindexes, GL_UNSIGNED_INT, s->mesh->indexes);
qglDrawElements(GL_TRIANGLES, s->mesh->numindexes, GL_INDEX_TYPE, s->mesh->indexes);
varray_ic = 0;
varray_vc = 0;
@ -2878,7 +2878,7 @@ void PPL_LightBModelTexturesFP(entity_t *e, dlight_t *light, vec3_t colour)
{
tnum = s->texinfo->texture;
t = GLR_TextureAnimation (tnum);
t = R_TextureAnimation (tnum);
p = 0;
if (t->gl_texturenumbumpmap && ppl_light_shader[p|PERMUTATION_BUMPMAP])
@ -2913,7 +2913,7 @@ void PPL_LightBModelTexturesFP(entity_t *e, dlight_t *light, vec3_t colour)
qglTexCoordPointer(2, GL_FLOAT, 0, s->mesh->st_array);
qglVertexPointer(3, GL_FLOAT, 0, s->mesh->xyz_array);
qglDrawElements(GL_TRIANGLES, s->mesh->numindexes, GL_UNSIGNED_INT, s->mesh->indexes);
qglDrawElements(GL_TRIANGLES, s->mesh->numindexes, GL_INDEX_TYPE, s->mesh->indexes);
}
@ -2954,7 +2954,7 @@ void PPL_LightBModelTextures(entity_t *e, dlight_t *light, vec3_t colour)
for (s = model->surfaces+model->firstmodelsurface,i = 0; i < model->nummodelsurfaces; i++, s++)
{
t = GLR_TextureAnimation (s->texinfo->texture);
t = R_TextureAnimation (s->texinfo->texture);
qglEnableClientState(GL_COLOR_ARRAY);
qglColorPointer(3, GL_FLOAT, sizeof(surfvertexarray_t), varray_v->stl);
@ -3043,7 +3043,7 @@ void PPL_LightBModelTextures(entity_t *e, dlight_t *light, vec3_t colour)
PPL_GenerateLightArrays(s, relativelightorigin, light, colour);
qglVertexPointer(3, GL_FLOAT, 0, s->mesh->xyz_array);
qglDrawElements(GL_TRIANGLES, s->mesh->numindexes, GL_UNSIGNED_INT, s->mesh->indexes);
qglDrawElements(GL_TRIANGLES, s->mesh->numindexes, GL_INDEX_TYPE, s->mesh->indexes);
varray_ic = 0;
varray_vc = 0;
}
@ -3702,7 +3702,7 @@ void PPL_RecursiveWorldNode_r (mnode_t *node)
shadowsurfcount++;
qglVertexPointer(3, GL_FLOAT, 0, surf->mesh->xyz_array);
qglDrawElements(GL_TRIANGLES, surf->mesh->numindexes, GL_UNSIGNED_INT, surf->mesh->indexes);
qglDrawElements(GL_TRIANGLES, surf->mesh->numindexes, GL_INDEX_TYPE, surf->mesh->indexes);
//fixme:this only works becuse q1bsps don't have combined meshes yet...
//back (depth precision doesn't matter)
@ -3877,7 +3877,7 @@ void PPL_RecursiveWorldNodeQ2_r (mnode_t *node)
//front face
qglVertexPointer(3, GL_FLOAT, 0, surf->mesh->xyz_array);
qglDrawElements(GL_TRIANGLES, surf->mesh->numindexes, GL_UNSIGNED_INT, surf->mesh->indexes);
qglDrawElements(GL_TRIANGLES, surf->mesh->numindexes, GL_INDEX_TYPE, surf->mesh->indexes);
//fixme:this only works becuse q1bsps don't have combined meshes yet...
//back (depth precision doesn't matter)
@ -3972,7 +3972,7 @@ void PPL_RecursiveWorldNodeQ3_r (mnode_t *node)
{
//front face
qglVertexPointer(3, GL_FLOAT, sizeof(GLfloat)*VERTEXSIZE, p->verts);
qglDrawElements(GL_TRIANGLES, (p->numverts-2)*3, GL_UNSIGNED_INT, varray_i_polytotri);
qglDrawElements(GL_TRIANGLES, (p->numverts-2)*3, GL_INDEX_TYPE, varray_i_polytotri);
//fixme...
for (v = 0; v < p->numverts; v++)
{
@ -4086,7 +4086,7 @@ void PPL_RecursiveWorldNode (dlight_t *dl)
{
qglEnableClientState(GL_VERTEX_ARRAY);
qglVertexPointer(3, GL_FLOAT, 0, dl->worldshadowmesh->verts);
qglDrawRangeElements(GL_TRIANGLES, 0, dl->worldshadowmesh->numverts, dl->worldshadowmesh->numindicies, GL_UNSIGNED_INT, dl->worldshadowmesh->indicies);
qglDrawRangeElements(GL_TRIANGLES, 0, dl->worldshadowmesh->numverts, dl->worldshadowmesh->numindicies, GL_INDEX_TYPE, dl->worldshadowmesh->indicies);
return;
}
@ -4491,7 +4491,7 @@ qboolean PPL_ScissorForBox(vec3_t mins, vec3_t maxs)
v[1] = (i & 2) ? mins[1] : maxs[1];
v[2] = (i & 4) ? mins[2] : maxs[2];
v[3] = 1.0f;
ML_Project(v, v2, r_refdef.viewangles, r_refdef.vieworg, (float)vid.width/vid.height, r_refdef.fov_y);
Matrix4_Project(v, v2, r_refdef.viewangles, r_refdef.vieworg, (float)vid.width/vid.height, r_refdef.fov_y);
v2[0]*=r_view_width;
v2[1]*=r_view_height;
// GL_TransformToScreen(v, v2);
@ -4561,7 +4561,7 @@ qboolean PPL_ScissorForBox(vec3_t mins, vec3_t maxs)
v[1] = v2[0] * vright[1] + v2[1] * vup[1] + v2[2] * vpn[1] + r_refdef.vieworg[1];
v[2] = v2[0] * vright[2] + v2[1] * vup[2] + v2[2] * vpn[2] + r_refdef.vieworg[2];
v[3] = 1.0f;
ML_Project(v, v2, r_refdef.viewangles, r_refdef.vieworg, vid.width/vid.height, r_refdef.fov_y);
Matrix4_Project(v, v2, r_refdef.viewangles, r_refdef.vieworg, vid.width/vid.height, r_refdef.fov_y);
v2[0]*=r_view_width;
v2[1]*=r_view_height;
// GL_TransformToScreen(v, v2);

View file

@ -20,11 +20,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// r_light.c
#include "quakedef.h"
#ifdef RGLQUAKE
#if defined(RGLQUAKE) || defined(D3DQUAKE)
#include "glquake.h"
int r_dlightframecount;
int d_lightstylevalue[256]; // 8.8 fraction of base light value
/*
==================
@ -64,6 +64,9 @@ void GLR_AnimateLight (void)
v2 = cl_lightstyle[j].map[v2] - 'a';
d_lightstylevalue[j] = (v1*(1-f) + v2*(f))*22;
if (d_lightstylevalue[j] > 255)
d_lightstylevalue[j] = 255;
}
}
@ -111,6 +114,7 @@ void R_InitBubble() {
}
}
#ifdef RGLQUAKE
void R_RenderDlight (dlight_t *light)
{
int i, j;
@ -157,7 +161,7 @@ void R_RenderDlight (dlight_t *light)
R_RenderDlights
=============
*/
void R_RenderDlights (void)
void GLR_RenderDlights (void)
{
int i;
dlight_t *l;
@ -206,7 +210,7 @@ void R_RenderDlights (void)
qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
qglDepthMask (1);
}
#endif
/*
=============================================================================

View file

@ -54,7 +54,7 @@ int r_framecount; // used for dlight push checking
float r_wateralphaval; //allowed or not...
mplane_t frustum[4];
//mplane_t frustum[4];
int c_brush_polys, c_alias_polys;
@ -79,8 +79,8 @@ vec3_t vpn;
vec3_t vright;
vec3_t r_origin;
float r_projection_matrix[16];
float r_view_matrix[16];
extern float r_projection_matrix[16];
extern float r_view_matrix[16];
//
// screen size info
@ -93,10 +93,7 @@ int r_viewcluster, r_viewcluster2, r_oldviewcluster, r_oldviewcluster2;
texture_t *r_notexture_mip;
int d_lightstylevalue[256]; // 8.8 fraction of base light value
void GLR_MarkLeaves (void);
//void R_MarkLeaves (void);
cvar_t r_norefresh = SCVAR("r_norefresh","0");
//cvar_t r_drawentities = SCVAR("r_drawentities","1");
@ -105,7 +102,7 @@ cvar_t r_norefresh = SCVAR("r_norefresh","0");
//cvar_t r_fullbright = SCVAR("r_fullbright","0");
cvar_t r_mirroralpha = SCVARF("r_mirroralpha","1", CVAR_CHEAT);
//cvar_t r_waterwarp = SCVAR("r_waterwarp", "0");
cvar_t r_novis = SCVAR("r_novis","0");
//cvar_t r_novis = SCVAR("r_novis","0");
//cvar_t r_netgraph = SCVAR("r_netgraph","0");
extern cvar_t gl_part_flame;
@ -122,7 +119,7 @@ cvar_t gl_finish = SCVAR("gl_finish","0");
cvar_t gl_contrast = SCVAR("gl_contrast", "1");
cvar_t gl_dither = SCVAR("gl_dither", "1");
cvar_t gl_maxdist = SCVAR("gl_maxdist", "8192");
cvar_t gl_mindist = SCVARF("gl_mindist", "4", CVAR_CHEAT); //by setting to 64 or something, you can use this as a wallhack
extern cvar_t gl_mindist;
extern cvar_t gl_motionblur;
extern cvar_t gl_motionblurscale;
@ -365,39 +362,6 @@ void GL_SetupSceneProcessingTextures (void)
qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, PP_WARP_TEX_SIZE, PP_WARP_TEX_SIZE, 0, GL_RGB, GL_UNSIGNED_BYTE, pp_edge_tex);
}
/*
=================
R_CullBox
Returns true if the box is completely outside the frustom
=================
*/
qboolean R_CullBox (vec3_t mins, vec3_t maxs)
{
int i;
for (i=0 ; i<4 ; i++)
if (BOX_ON_PLANE_SIDE (mins, maxs, &frustum[i]) == 2)
return true;
return false;
}
qboolean R_CullSphere (vec3_t org, float radius)
{
//four frustrum planes all point inwards in an expanding 'cone'.
int i;
float d;
for (i=0 ; i<4 ; i++)
{
d = DotProduct(frustum[i].normal, org)-frustum[i].dist;
if (d <= -radius)
return true;
}
return false;
}
void R_RotateForEntity (entity_t *e)
{
float m[16];
@ -462,6 +426,7 @@ void R_RotateForEntity (entity_t *e)
R_GetSpriteFrame
================
*/
/*
mspriteframe_t *R_GetSpriteFrame (entity_t *currententity)
{
msprite_t *psprite;
@ -512,7 +477,7 @@ mspriteframe_t *R_GetSpriteFrame (entity_t *currententity)
return pspriteframe;
}
*/
/*
=================
@ -535,7 +500,7 @@ void R_DrawSpriteModel (entity_t *e)
mesh_t mesh;
vec2_t texcoords[4]={{0, 1},{0,0},{1,0},{1,1}};
vec3_t vertcoords[4];
int indexes[6] = {0, 1, 2, 0, 2, 3};
index_t indexes[6] = {0, 1, 2, 0, 2, 3};
byte_vec4_t colours[4];
float x, y;
@ -890,100 +855,6 @@ void GLR_BrightenScreen (void)
RSpeedEnd(RSPEED_PALETTEFLASHES);
}
int SignbitsForPlane (mplane_t *out)
{
int bits, j;
// for fast box on planeside test
bits = 0;
for (j=0 ; j<3 ; j++)
{
if (out->normal[j] < 0)
bits |= 1<<j;
}
return bits;
}
#if 1
void R_SetFrustum (void)
{
float scale;
int i;
float mvp[16];
if ((int)r_novis.value & 4)
return;
Matrix4_Multiply(r_projection_matrix, r_view_matrix, mvp);
for (i = 0; i < 4; i++)
{
if (i & 1)
{
frustum[i].normal[0] = mvp[3] + mvp[0+i/2];
frustum[i].normal[1] = mvp[7] + mvp[4+i/2];
frustum[i].normal[2] = mvp[11] + mvp[8+i/2];
frustum[i].dist = mvp[15] + mvp[12+i/2];
}
else
{
frustum[i].normal[0] = mvp[3] - mvp[0+i/2];
frustum[i].normal[1] = mvp[7] - mvp[4+i/2];
frustum[i].normal[2] = mvp[11] - mvp[8+i/2];
frustum[i].dist = mvp[15] - mvp[12+i/2];
}
scale = 1/sqrt(DotProduct(frustum[i].normal, frustum[i].normal));
frustum[i].normal[0] *= scale;
frustum[i].normal[1] *= scale;
frustum[i].normal[2] *= scale;
frustum[i].dist *= -scale;
frustum[i].type = PLANE_ANYZ;
frustum[i].signbits = SignbitsForPlane (&frustum[i]);
}
}
#else
void R_SetFrustum (void)
{
int i;
if ((int)r_novis.value & 4)
return;
/* removed - assumes fov_x == fov_y
if (r_refdef.fov_x == 90)
{
// front side is visible
VectorAdd (vpn, vright, frustum[0].normal);
VectorSubtract (vpn, vright, frustum[1].normal);
VectorAdd (vpn, vup, frustum[2].normal);
VectorSubtract (vpn, vup, frustum[3].normal);
}
else
*/
{
// rotate VPN right by FOV_X/2 degrees
RotatePointAroundVector( frustum[0].normal, vup, vpn, -(90-r_refdef.fov_x / 2 ) );
// rotate VPN left by FOV_X/2 degrees
RotatePointAroundVector( frustum[1].normal, vup, vpn, 90-r_refdef.fov_x / 2 );
// rotate VPN up by FOV_X/2 degrees
RotatePointAroundVector( frustum[2].normal, vright, vpn, 90-r_refdef.fov_y / 2 );
// rotate VPN down by FOV_X/2 degrees
RotatePointAroundVector( frustum[3].normal, vright, vpn, -( 90 - r_refdef.fov_y / 2 ) );
}
for (i=0 ; i<4 ; i++)
{
frustum[i].type = PLANE_ANYZ;
frustum[i].dist = DotProduct (r_origin, frustum[i].normal);
frustum[i].signbits = SignbitsForPlane (&frustum[i]);
}
}
#endif
/*
===============
R_SetupFrame
@ -1100,98 +971,6 @@ void GLR_SetupFrame (void)
}
void MYgluPerspective( GLdouble fovx, GLdouble fovy,
GLdouble zNear, GLdouble zFar )
{
GLdouble xmin, xmax, ymin, ymax;
ymax = zNear * tan( fovy * M_PI / 360.0 );
ymin = -ymax;
xmax = zNear * tan( fovx * M_PI / 360.0 );
xmin = -xmax;
r_projection_matrix[0] = (2*zNear) / (xmax - xmin);
r_projection_matrix[4] = 0;
r_projection_matrix[8] = (xmax + xmin) / (xmax - xmin);
r_projection_matrix[12] = 0;
r_projection_matrix[1] = 0;
r_projection_matrix[5] = (2*zNear) / (ymax - ymin);
r_projection_matrix[9] = (ymax + ymin) / (ymax - ymin);
r_projection_matrix[13] = 0;
r_projection_matrix[2] = 0;
r_projection_matrix[6] = 0;
r_projection_matrix[10] = - (zFar+zNear)/(zFar-zNear);
r_projection_matrix[14] = - (2.0f*zFar*zNear)/(zFar-zNear);
r_projection_matrix[3] = 0;
r_projection_matrix[7] = 0;
r_projection_matrix[11] = -1;
r_projection_matrix[15] = 0;
}
void GL_InfinatePerspective( GLdouble fovx, GLdouble fovy,
GLdouble zNear)
{
// nudge infinity in just slightly for lsb slop
GLfloat nudge = 1;// - 1.0 / (1<<23);
GLdouble xmin, xmax, ymin, ymax;
ymax = zNear * tan( fovy * M_PI / 360.0 );
ymin = -ymax;
xmax = zNear * tan( fovx * M_PI / 360.0 );
xmin = -xmax;
r_projection_matrix[0] = (2*zNear) / (xmax - xmin);
r_projection_matrix[4] = 0;
r_projection_matrix[8] = (xmax + xmin) / (xmax - xmin);
r_projection_matrix[12] = 0;
r_projection_matrix[1] = 0;
r_projection_matrix[5] = (2*zNear) / (ymax - ymin);
r_projection_matrix[9] = (ymax + ymin) / (ymax - ymin);
r_projection_matrix[13] = 0;
r_projection_matrix[2] = 0;
r_projection_matrix[6] = 0;
r_projection_matrix[10] = -1 * nudge;
r_projection_matrix[14] = -2*zNear * nudge;
r_projection_matrix[3] = 0;
r_projection_matrix[7] = 0;
r_projection_matrix[11] = -1;
r_projection_matrix[15] = 0;
}
void GL_ParallelPerspective(GLdouble xmin, GLdouble xmax, GLdouble ymax, GLdouble ymin,
GLdouble znear, GLdouble zfar)
{
r_projection_matrix[0] = 2/(xmax-xmin);
r_projection_matrix[4] = 0;
r_projection_matrix[8] = 0;
r_projection_matrix[12] = (xmax+xmin)/(xmax-xmin);
r_projection_matrix[1] = 0;
r_projection_matrix[5] = 2/(ymax-ymin);
r_projection_matrix[9] = 0;
r_projection_matrix[13] = (ymax+ymin)/(ymax-ymin);
r_projection_matrix[2] = 0;
r_projection_matrix[6] = 0;
r_projection_matrix[10] = -2/(zfar-znear);
r_projection_matrix[14] = (zfar+znear)/(zfar-znear);
r_projection_matrix[3] = 0;
r_projection_matrix[7] = 0;
r_projection_matrix[11] = 0;
r_projection_matrix[15] = 1;
}
/*
=============
R_SetupGL
@ -1293,7 +1072,7 @@ void R_SetupGL (void)
qglMatrixMode(GL_MODELVIEW);
ML_ModelViewMatrixFromAxis(r_view_matrix, vpn, vright, vup, r_refdef.vieworg);
Matrix4_ModelViewMatrixFromAxis(r_view_matrix, vpn, vright, vup, r_refdef.vieworg);
qglLoadMatrixf(r_view_matrix);
//
@ -1367,7 +1146,7 @@ void R_RenderScene (void)
#endif
{
TRACE(("dbg: calling GLR_MarkLeaves\n"));
GLR_MarkLeaves (); // done here so we know if we're in water
R_MarkLeaves (); // done here so we know if we're in water
TRACE(("dbg: calling R_DrawWorld\n"));
R_DrawWorld (); // adds static entities to the list
}
@ -1384,7 +1163,7 @@ void R_RenderScene (void)
GL_DisableMultitexture();
TRACE(("dbg: calling R_RenderDlights\n"));
R_RenderDlights ();
GLR_RenderDlights ();
if (!(r_refdef.flags & Q2RDF_NOWORLDMODEL))
{
@ -1541,7 +1320,7 @@ void R_Mirror (void)
for (prevs = s; s; s=s->nextalphasurface) //write the polys to the stencil buffer.
{
qglVertexPointer(3, GL_FLOAT, 0, s->mesh->xyz_array);
qglDrawElements(GL_TRIANGLES, s->mesh->numindexes, GL_UNSIGNED_INT, s->mesh->indexes);
qglDrawElements(GL_TRIANGLES, s->mesh->numindexes, GL_INDEX_TYPE, s->mesh->indexes);
}

View file

@ -41,7 +41,7 @@ int *lightmap_textures;
int *deluxmap_textures;
int detailtexture;
#define MAX_LIGHTMAP_SIZE 256
#define MAX_LIGHTMAP_SIZE LMBLOCK_WIDTH
vec3_t blocknormals[MAX_LIGHTMAP_SIZE*MAX_LIGHTMAP_SIZE];
unsigned blocklights[MAX_LIGHTMAP_SIZE*MAX_LIGHTMAP_SIZE];
@ -1665,42 +1665,6 @@ store:
#endif
}
/*
===============
R_TextureAnimation
Returns the proper texture for a given time and base texture
===============
*/
texture_t *GLR_TextureAnimation (texture_t *base)
{
int reletive;
int count;
if (currententity->frame)
{
if (base->alternate_anims)
base = base->alternate_anims;
}
if (!base->anim_total)
return base;
reletive = (int)(cl.time*10) % base->anim_total;
count = 0;
while (base->anim_min > reletive || base->anim_max <= reletive)
{
base = base->anim_next;
if (!base)
Sys_Error ("R_TextureAnimation: broken cycle");
if (++count > 100)
Sys_Error ("R_TextureAnimation: infinite cycle");
}
return base;
}
/*
=============================================================
@ -1758,7 +1722,7 @@ static void DrawGLPoly (mesh_t *mesh)
qglEnableClientState( GL_VERTEX_ARRAY );
qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
qglTexCoordPointer(2, GL_FLOAT, 0, mesh->st_array);
qglDrawElements(GL_TRIANGLES, mesh->numindexes, GL_UNSIGNED_INT, mesh->indexes);
qglDrawElements(GL_TRIANGLES, mesh->numindexes, GL_INDEX_TYPE, mesh->indexes);
R_IBrokeTheArrays();
/*
@ -1892,11 +1856,11 @@ void R_RenderBrushPoly (msurface_t *fa)
if (fa->flags & SURF_DRAWSKY)
{ // warp texture, no lightmaps
EmitBothSkyLayers (fa);
GL_EmitBothSkyLayers (fa);
return;
}
t = GLR_TextureAnimation (fa->texinfo->texture);
t = R_TextureAnimation (fa->texinfo->texture);
GL_Bind (t->gl_texturenum);
if (fa->flags & SURF_DRAWTURB)
@ -2328,6 +2292,7 @@ void VectorVectors(vec3_t forward, vec3_t right, vec3_t up);
DrawTextureChains
================
*/
/*
#if 0
static void DrawTextureChains (model_t *model, float alpha, vec3_t relativelightorigin)
{
@ -2353,7 +2318,7 @@ static void DrawTextureChains (model_t *model, float alpha, vec3_t relativelight
if (s)
{
t->texturechain = NULL;
R_DrawSkyChain (s);
GL_DrawSkyChain (s);
}
}
}
@ -2383,7 +2348,7 @@ static void DrawTextureChains (model_t *model, float alpha, vec3_t relativelight
continue;
t->texturechain = NULL;
if (i == skytexturenum && model == cl.worldmodel)
R_DrawSkyChain (s);
GL_DrawSkyChain (s);
else if (i == mirrortexturenum && model == cl.worldmodel && r_mirroralpha.value != 1.0)
R_MirrorChain (s);
else
@ -2399,7 +2364,7 @@ static void DrawTextureChains (model_t *model, float alpha, vec3_t relativelight
else
first = s;
t = GLR_TextureAnimation (t);
t = R_TextureAnimation (t);
cf = s;
@ -2674,11 +2639,13 @@ static void DrawTextureChains (model_t *model, float alpha, vec3_t relativelight
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
#endif
*/
/*
=================
R_DrawBrushModel
=================
*/
/*
#if 0
static void R_DrawBrushModel (entity_t *e)
{
@ -2794,7 +2761,7 @@ e->angles[0] = -e->angles[0]; // stupid quake bug
glPopMatrix ();
}
#endif
*/
/*
=============================================================
@ -3038,6 +3005,7 @@ static void GLR_RecursiveQ2WorldNode (mnode_t *node)
#endif
#ifdef Q3BSPS
mleaf_t *r_vischain; // linked list of visible leafs
static void GLR_LeafWorldNode (void)
{
int i;
@ -3175,174 +3143,6 @@ qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
qbyte *Q1BSP_LeafPVS (model_t *model, mleaf_t *leaf, qbyte *buffer);
/*
===============
R_MarkLeaves
===============
*/
void GLR_MarkLeaves (void)
{
qbyte fatvis[MAX_MAP_LEAFS/8];
qbyte *vis;
mnode_t *node;
int i;
qbyte solid[4096];
#ifdef Q3BSPS
if (cl.worldmodel->fromgame == fg_quake3)
{
int cluster;
mleaf_t *leaf;
if (r_oldviewcluster == r_viewcluster && !r_novis.value && r_viewcluster != -1)
return;
// development aid to let you run around and see exactly where
// the pvs ends
// if (r_lockpvs->value)
// return;
r_vischain = NULL;
r_visframecount++;
r_oldviewcluster = r_viewcluster;
if (r_novis.value || r_viewcluster == -1 || !cl.worldmodel->vis )
{
// mark everything
for (i=0,leaf=cl.worldmodel->leafs ; i<cl.worldmodel->numleafs ; i++, leaf++)
{
if ( !leaf->nummarksurfaces ) {
continue;
}
leaf->visframe = r_visframecount;
leaf->vischain = r_vischain;
r_vischain = leaf;
}
return;
}
vis = CM_ClusterPVS (cl.worldmodel, r_viewcluster, NULL);//, cl.worldmodel);
for (i=0,leaf=cl.worldmodel->leafs ; i<cl.worldmodel->numleafs ; i++, leaf++)
{
cluster = leaf->cluster;
if ( cluster == -1 || !leaf->nummarksurfaces ) {
continue;
}
if ( vis[cluster>>3] & (1<<(cluster&7)) ) {
leaf->visframe = r_visframecount;
leaf->vischain = r_vischain;
r_vischain = leaf;
}
}
return;
}
#endif
#ifdef Q2BSPS
if (cl.worldmodel->fromgame == fg_quake2)
{
int c;
mleaf_t *leaf;
int cluster;
if (r_oldviewcluster == r_viewcluster && r_oldviewcluster2 == r_viewcluster2)
return;
r_oldviewcluster = r_viewcluster;
r_oldviewcluster2 = r_viewcluster2;
if (r_novis.value == 2)
return;
r_visframecount++;
if (r_novis.value || r_viewcluster == -1 || !cl.worldmodel->vis)
{
// mark everything
for (i=0 ; i<cl.worldmodel->numleafs ; i++)
cl.worldmodel->leafs[i].visframe = r_visframecount;
for (i=0 ; i<cl.worldmodel->numnodes ; i++)
cl.worldmodel->nodes[i].visframe = r_visframecount;
return;
}
vis = CM_ClusterPVS (cl.worldmodel, r_viewcluster, NULL);//, cl.worldmodel);
// may have to combine two clusters because of solid water boundaries
if (r_viewcluster2 != r_viewcluster)
{
memcpy (fatvis, vis, (cl.worldmodel->numleafs+7)/8);
vis = CM_ClusterPVS (cl.worldmodel, r_viewcluster2, NULL);//, cl.worldmodel);
c = (cl.worldmodel->numleafs+31)/32;
for (i=0 ; i<c ; i++)
((int *)fatvis)[i] |= ((int *)vis)[i];
vis = fatvis;
}
for (i=0,leaf=cl.worldmodel->leafs ; i<cl.worldmodel->numleafs ; i++, leaf++)
{
cluster = leaf->cluster;
if (cluster == -1)
continue;
if (vis[cluster>>3] & (1<<(cluster&7)))
{
node = (mnode_t *)leaf;
do
{
if (node->visframe == r_visframecount)
break;
node->visframe = r_visframecount;
node = node->parent;
} while (node);
}
}
return;
}
#endif
if (((r_oldviewleaf == r_viewleaf && r_oldviewleaf2 == r_viewleaf2) && !r_novis.value) || r_novis.value == 2)
return;
// if (mirror)
// return;
r_visframecount++;
r_oldviewleaf = r_viewleaf;
r_oldviewleaf2 = r_viewleaf2;
if (r_novis.value)
{
vis = solid;
memset (solid, 0xff, (cl.worldmodel->numleafs+7)>>3);
}
else if (r_viewleaf2)
{
int c;
Q1BSP_LeafPVS (cl.worldmodel, r_viewleaf2, fatvis);
vis = Q1BSP_LeafPVS (cl.worldmodel, r_viewleaf, NULL);
c = (cl.worldmodel->numleafs+31)/32;
for (i=0 ; i<c ; i++)
((int *)fatvis)[i] |= ((int *)vis)[i];
vis = fatvis;
}
else
vis = Q1BSP_LeafPVS (cl.worldmodel, r_viewleaf, NULL);
for (i=0 ; i<cl.worldmodel->numleafs ; i++)
{
if (vis[i>>3] & (1<<(i&7)))
{
node = (mnode_t *)&cl.worldmodel->leafs[i+1];
do
{
if (node->visframe == r_visframecount)
break;
node->visframe = r_visframecount;
node = node->parent;
} while (node);
}
}
}
/*
@ -3471,7 +3271,7 @@ int nColinElim;
BuildSurfaceDisplayList
================
*/
void BuildSurfaceDisplayList (msurface_t *fa)
void GL_BuildSurfaceDisplayList (msurface_t *fa)
{
int i, lindex, lnumverts;
medge_t *pedges, *r_pedge;
@ -3837,7 +3637,7 @@ void GL_BuildLightmaps (void)
P_EmitSkyEffectTris(m, &m->surfaces[i]);
if (m->surfaces[i].mesh) //there are some surfaces that have a display list already (the subdivided ones)
continue;
BuildSurfaceDisplayList (m->surfaces + i);
GL_BuildSurfaceDisplayList (m->surfaces + i);
}
}

View file

@ -42,77 +42,6 @@ extern int scr_chatmode;
extern cvar_t scr_chatmodecvar;
void RSpeedShow(void)
{
int i;
static int samplerspeeds[RSPEED_MAX];
static int samplerquant[RQUANT_MAX];
char *RSpNames[RSPEED_MAX];
char *RQntNames[RQUANT_MAX];
char *s;
static int framecount;
if (!r_speeds.value)
return;
memset(RSpNames, 0, sizeof(RSpNames));
RSpNames[RSPEED_TOTALREFRESH] = "Total refresh";
RSpNames[RSPEED_PROTOCOL] = "Protocol";
RSpNames[RSPEED_LINKENTITIES] = "Entity setup";
RSpNames[RSPEED_WORLDNODE] = "World walking";
RSpNames[RSPEED_WORLD] = "World rendering";
RSpNames[RSPEED_DYNAMIC] = "Lightmap updates";
RSpNames[RSPEED_PARTICLES] = "Particle physics and sorting";
RSpNames[RSPEED_PARTICLESDRAW] = "Particle drawing";
RSpNames[RSPEED_2D] = "2d elements";
RSpNames[RSPEED_SERVER] = "Server";
RSpNames[RSPEED_DRAWENTITIES] = "Entity rendering";
RSpNames[RSPEED_PALETTEFLASHES] = "Palette flashes";
RSpNames[RSPEED_STENCILSHADOWS] = "Stencil Shadows";
RSpNames[RSPEED_FULLBRIGHTS] = "World fullbrights";
RSpNames[RSPEED_FINISH] = "Waiting for card to catch up";
RQntNames[RQUANT_MSECS] = "Microseconds";
RQntNames[RQUANT_EPOLYS] = "Entity Polys";
RQntNames[RQUANT_WPOLYS] = "World Polys";
RQntNames[RQUANT_SHADOWFACES] = "Shadow Faces";
RQntNames[RQUANT_SHADOWEDGES] = "Shadow edges";
RQntNames[RQUANT_LITFACES] = "Lit faces";
for (i = 0; i < RSPEED_MAX; i++)
{
s = va("%i %-30s", samplerspeeds[i], RSpNames[i]);
Draw_String(vid.width-strlen(s)*8, i*8, s);
}
for (i = 0; i < RQUANT_MAX; i++)
{
s = va("%i %-30s", samplerquant[i], RQntNames[i]);
Draw_String(vid.width-strlen(s)*8, (i+RSPEED_MAX)*8, s);
}
s = va("%f %-30s", 100000000.0f/samplerspeeds[RSPEED_TOTALREFRESH], "Framerate");
Draw_String(vid.width-strlen(s)*8, (i+RSPEED_MAX)*8, s);
if (framecount++>=100)
{
for (i = 0; i < RSPEED_MAX; i++)
{
samplerspeeds[i] = rspeeds[i];
rspeeds[i] = 0;
}
for (i = 0; i < RQUANT_MAX; i++)
{
samplerquant[i] = rquant[i];
rquant[i] = 0;
}
framecount=0;
}
}
// console size manipulation callbacks
void GLVID_Console_Resize(void)
{

View file

@ -167,13 +167,6 @@ const char *gl_renderer;
const char *gl_version;
const char *gl_extensions;
//int texture_mode = GL_NEAREST;
//int texture_mode = GL_NEAREST_MIPMAP_NEAREST;
//int texture_mode = GL_NEAREST_MIPMAP_LINEAR;
int texture_mode = GL_LINEAR;
//int texture_mode = GL_LINEAR_MIPMAP_NEAREST;
//int texture_mode = GL_LINEAR_MIPMAP_LINEAR;
int texture_extension_number = 1;
void APIENTRY GL_DrawRangeElementsEmul(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices)

View file

@ -85,7 +85,6 @@ static qboolean vid_initialized = false;
static qboolean leavecurrentmode= true;
static qboolean vid_canalttab = false;
static qboolean vid_wassuspended = false;
static int windowed_mouse;
extern qboolean mouseactive; // from in_win.c
static HICON hIcon;
extern qboolean vid_isfullscreen;
@ -910,16 +909,14 @@ void GL_DoSwap (void)
{
if (!_windowed_mouse.value)
{
if (windowed_mouse)
if (mouseactive)
{
IN_DeactivateMouse ();
IN_ShowMouse ();
windowed_mouse = false;
}
}
else
{
windowed_mouse = true;
if ((key_dest == key_game||mouseusedforgui) && !mouseactive && ActiveApp)
{
IN_ActivateMouse ();

View file

@ -20,8 +20,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// gl_warp.c -- sky and water polygons
#include "quakedef.h"
#ifdef RGLQUAKE
#if defined(RGLQUAKE) || defined(D3DQUAKE)
#include "glquake.h"
#ifdef D3DQUAKE
#include "d3dquake.h"
#endif
#ifdef Q3SHADERS
#include "shader.h"
#endif
@ -30,7 +33,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
extern void GL_DrawAliasMesh (mesh_t *mesh, int texnum);
void R_DrawSkySphere (msurface_t *fa);
void GL_DrawSkySphere (msurface_t *fa);
void D3D7_DrawSkySphere (msurface_t *fa);
void D3D9_DrawSkySphere (msurface_t *fa);
extern model_t *loadmodel;
@ -55,7 +60,7 @@ char defaultskybox[MAX_QPATH];
int skyboxtex[6];
void R_DrawSkyBox (msurface_t *s);
void GL_DrawSkyBox (msurface_t *s);
void BoundPoly (int numverts, float *verts, vec3_t mins, vec3_t maxs)
{
int i, j;
@ -92,6 +97,7 @@ EmitWaterPolys
Does a water warp on the pre-fragmented glpoly_t chain
=============
*/
#ifdef RGLQUAKE
void EmitWaterPolys (msurface_t *fa, float basealpha)
{
float a;
@ -167,7 +173,7 @@ This will be called for brushmodels, the world
will have them chained together.
===============
*/
void EmitBothSkyLayers (msurface_t *fa)
void GL_EmitBothSkyLayers (msurface_t *fa)
{
GL_DisableMultitexture();
@ -187,13 +193,16 @@ void EmitBothSkyLayers (msurface_t *fa)
qglDisable (GL_BLEND);
}
#endif
/*
=================
R_DrawSkyChain
GL_DrawSkyChain
=================
*/
#ifdef RGLQUAKE
void R_DrawSkyBoxChain (msurface_t *s);
void R_DrawSkyChain (msurface_t *s)
void GL_DrawSkyChain (msurface_t *s)
{
msurface_t *fa;
@ -229,7 +238,7 @@ void R_DrawSkyChain (msurface_t *s)
for (fa=s ; fa ; fa=fa->texturechain)
{
qglVertexPointer(3, GL_FLOAT, 0, fa->mesh->xyz_array);
qglDrawElements(GL_TRIANGLES, fa->mesh->numindexes, GL_UNSIGNED_INT, fa->mesh->indexes);
qglDrawElements(GL_TRIANGLES, fa->mesh->numindexes, GL_INDEX_TYPE, fa->mesh->indexes);
}
R_IBrokeTheArrays();
@ -245,7 +254,7 @@ void R_DrawSkyChain (msurface_t *s)
}
// if (usingskydome)
{
R_DrawSkySphere(s);
GL_DrawSkySphere(s);
return;
}
@ -269,6 +278,116 @@ void R_DrawSkyChain (msurface_t *s)
qglDisable (GL_BLEND);
}
#endif
#ifdef D3DQUAKE
void R_DrawSkyBoxChain (msurface_t *s);
void D3D7_DrawSkyChain (msurface_t *s)
{
msurface_t *fa;
#ifdef Q3SHADERS
if (!solidskytexture&&!usingskybox)
{
int i;
if (s->texinfo->texture->shader && s->texinfo->texture->shader->skydome)
{
for (i = 0; i < 6; i++)
{
skyboxtex[i] = s->texinfo->texture->shader->skydome->farbox_textures[i];
}
solidskytexture = 1;
}
}
#endif
/*
if (r_fastsky.value||(!solidskytexture&&!usingskybox)) //this is for visability only... we'd otherwise not stoop this low (and this IS low)
{
int fc;
qbyte *pal;
fc = r_fastskycolour.value;
if (fc > 255)
fc = 255;
if (fc < 0)
fc = 0;
pal = host_basepal+fc*3;
qglDisable(GL_TEXTURE_2D);
qglColor3f(pal[0]/255.0f, pal[1]/255.0f, pal[2]/255.0f);
qglDisableClientState( GL_COLOR_ARRAY );
for (fa=s ; fa ; fa=fa->texturechain)
{
qglVertexPointer(3, GL_FLOAT, 0, fa->mesh->xyz_array);
qglDrawElements(GL_TRIANGLES, fa->mesh->numindexes, GL_INDEX_TYPE, fa->mesh->indexes);
}
R_IBrokeTheArrays();
qglColor3f(1, 1, 1);
qglEnable(GL_TEXTURE_2D);
return;
}
*/
/* if (usingskybox)
{
R_DrawSkyBoxChain(s);
return;
}
*/
D3D7_DrawSkySphere(s);
}
void D3D9_DrawSkyChain (msurface_t *s)
{
msurface_t *fa;
#ifdef Q3SHADERS
if (!solidskytexture&&!usingskybox)
{
int i;
if (s->texinfo->texture->shader && s->texinfo->texture->shader->skydome)
{
for (i = 0; i < 6; i++)
{
skyboxtex[i] = s->texinfo->texture->shader->skydome->farbox_textures[i];
}
solidskytexture = 1;
}
}
#endif
/*
if (r_fastsky.value||(!solidskytexture&&!usingskybox)) //this is for visability only... we'd otherwise not stoop this low (and this IS low)
{
int fc;
qbyte *pal;
fc = r_fastskycolour.value;
if (fc > 255)
fc = 255;
if (fc < 0)
fc = 0;
pal = host_basepal+fc*3;
qglDisable(GL_TEXTURE_2D);
qglColor3f(pal[0]/255.0f, pal[1]/255.0f, pal[2]/255.0f);
qglDisableClientState( GL_COLOR_ARRAY );
for (fa=s ; fa ; fa=fa->texturechain)
{
qglVertexPointer(3, GL_FLOAT, 0, fa->mesh->xyz_array);
qglDrawElements(GL_TRIANGLES, fa->mesh->numindexes, GL_INDEX_TYPE, fa->mesh->indexes);
}
R_IBrokeTheArrays();
qglColor3f(1, 1, 1);
qglEnable(GL_TEXTURE_2D);
return;
}
*/
/* if (usingskybox)
{
R_DrawSkyBoxChain(s);
return;
}
*/
D3D9_DrawSkySphere(s);
}
#endif
/*
=================================================================
@ -338,8 +457,14 @@ void GLR_LoadSkys (void)
if (!skyboxtex[i])
break;
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
#ifdef RGLQUAKE
//so the user can specify GL_NEAREST and still get nice skyboxes... yeah, a hack
if (qrenderer == QR_OPENGL)
{
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
#endif
}
if (boxname != defaultskybox && i < 6 && *defaultskybox)
{
@ -585,7 +710,7 @@ void ClipSkyPolygon (int nump, vec3_t vecs, int stage)
/*
=================
R_DrawSkyChain
R_DrawSkyBoxChain
=================
*/
void R_DrawSkyBoxChain (msurface_t *s)
@ -611,7 +736,13 @@ void R_DrawSkyBoxChain (msurface_t *s)
}
}
R_DrawSkyBox (s);
#ifdef RGLQUAKE
if (qrenderer == QR_OPENGL)
{
GL_DrawSkyBox (s);
return;
}
#endif
}
#define skygridx 16
@ -622,16 +753,106 @@ void R_DrawSkyBoxChain (msurface_t *s)
#define skygridyrecip (1.0f / (skygridy))
#define skysphere_numverts (skygridx1 * skygridy1)
#define skysphere_numtriangles (skygridx * skygridy * 2)
static float skysphere_vertex3f[skysphere_numverts * 3];
static float skysphere_texcoord2f[skysphere_numverts * 2];
static int skysphere_element3i[skysphere_numtriangles * 3];
mesh_t skymesh;
int skymade;
static index_t skysphere_element3i[skysphere_numtriangles * 3];
static float skysphere_texcoord2f[skysphere_numverts * 2];
static void skyspherecalc(int skytype)
#ifdef D3DQUAKE
static float skysphere_d3dvertex[skysphere_numverts * 5];
static d3d_animateskysphere(float time)
{
int i;
float *d3dvert, *texcoord2f;
d3dvert = skysphere_d3dvertex;
texcoord2f = skysphere_texcoord2f;
for (i = 0; i < skysphere_numverts; i++)
{
d3dvert[3] = time+*texcoord2f++;
d3dvert[4] = time+*texcoord2f++;
d3dvert+=5;
}
}
static void d3d_skyspherecalc(int skytype)
{ //yes, this is basically stolen from DarkPlaces
int i, j, *e;
int i, j;
index_t *e;
float a, b, x, ax, ay, v[3], length, *d3dvert, *texcoord2f;
float dx, dy, dz;
float texscale;
if (skymade == skytype+500)
return;
skymade = skytype+500;
if (skytype == 2)
texscale = 1/16.0f;
else
texscale = 1/1.5f;
texscale*=3;
dx = 16;
dy = 16;
dz = 16 / 3;
d3dvert = skysphere_d3dvertex;
texcoord2f = skysphere_texcoord2f;
for (j = 0;j <= skygridy;j++)
{
a = j * skygridyrecip;
ax = cos(a * M_PI * 2);
ay = -sin(a * M_PI * 2);
for (i = 0;i <= skygridx;i++)
{
b = i * skygridxrecip;
x = cos((b + 0.5) * M_PI);
v[0] = ax*x * dx;
v[1] = ay*x * dy;
v[2] = -sin((b + 0.5) * M_PI) * dz;
length = texscale / sqrt(v[0]*v[0]+v[1]*v[1]+(v[2]*v[2]*9));
*d3dvert++ = v[0]*1000;
*d3dvert++ = v[1]*1000;
*d3dvert++ = v[2]*1000;
d3dvert+=2;
*texcoord2f++ = v[0] * length;
*texcoord2f++ = v[1] * length;
}
}
e = skysphere_element3i;
for (j = 0;j < skygridy;j++)
{
for (i = 0;i < skygridx;i++)
{
*e++ = j * skygridx1 + i;
*e++ = j * skygridx1 + i + 1;
*e++ = (j + 1) * skygridx1 + i;
*e++ = j * skygridx1 + i + 1;
*e++ = (j + 1) * skygridx1 + i + 1;
*e++ = (j + 1) * skygridx1 + i;
}
}
}
#endif
#ifdef RGLQUAKE
static float skysphere_vertex3f[skysphere_numverts * 3];
mesh_t skymesh;
static void gl_skyspherecalc(int skytype)
{ //yes, this is basically stolen from DarkPlaces
int i, j;
index_t *e;
float a, b, x, ax, ay, v[3], length, *vertex3f, *texcoord2f;
float dx, dy, dz;
@ -697,7 +918,8 @@ static void skyspherecalc(int skytype)
}
}
}
void R_DrawSkySphere (msurface_t *fa)
void GL_DrawSkySphere (msurface_t *fa)
{
extern cvar_t gl_maxdist;
float time = cl.gametime+realtime-cl.gametimemark;
@ -718,7 +940,7 @@ void R_DrawSkySphere (msurface_t *fa)
if (fa->texinfo->texture->shader)
{ //the shader route.
meshbuffer_t mb;
skyspherecalc(2);
gl_skyspherecalc(2);
mb.sortkey = 0;
mb.infokey = -1;
mb.dlightbits = 0;
@ -732,7 +954,7 @@ void R_DrawSkySphere (msurface_t *fa)
else
#endif
{ //the boring route.
skyspherecalc(1);
gl_skyspherecalc(1);
qglMatrixMode(GL_TEXTURE);
qglPushMatrix();
qglTranslatef(time*8/128, time*8/128, 0);
@ -759,6 +981,169 @@ void R_DrawSkySphere (msurface_t *fa)
qglColorMask(1,1,1,1);
}
}
#endif
#ifdef D3DQUAKE
void D3D7_DrawSkySphere (msurface_t *fa)
{
extern cvar_t gl_maxdist;
float time = cl.gametime+realtime-cl.gametimemark;
float skydist = 99999;//gl_maxdist.value;
if (skydist<1)
skydist=gl_skyboxdist.value;
skydist/=16;
//scale sky sphere and place around view origin.
// qglPushMatrix();
// qglTranslatef(r_refdef.vieworg[0], r_refdef.vieworg[1], r_refdef.vieworg[2]);
// qglScalef(skydist, skydist, skydist);
//draw in bulk? this is eeevil
//FIXME: We should use the skybox clipping code and split the sphere into 6 sides.
/*#ifdef Q3SHADERS
if (fa->texinfo->texture->shader)
{ //the shader route.
meshbuffer_t mb;
d3d_skyspherecalc(2);
mb.sortkey = 0;
mb.infokey = -1;
mb.dlightbits = 0;
mb.entity = &r_worldentity;
mb.shader = fa->texinfo->texture->shader;
mb.fog = NULL;
mb.mesh = &skymesh;
R_PushMesh(mb.mesh, mb.shader->features);
R_RenderMeshBuffer(&mb, false);
}
else
#endif*/
{ //the boring route.
d3d_skyspherecalc(1);
// qglMatrixMode(GL_TEXTURE);
// qglPushMatrix();
// qglTranslatef(time*8/128, time*8/128, 0);
pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHATESTENABLE, FALSE );
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
// pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG2, D3DTA_CURRENT);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
// pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA);
pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA);
d3d_animateskysphere(time*8/128);
pD3DDev->lpVtbl->SetTexture(pD3DDev, 0, (LPDIRECTDRAWSURFACE7)solidskytexture);
pD3DDev->lpVtbl->DrawIndexedPrimitive(pD3DDev, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_TEX1, skysphere_d3dvertex, skysphere_numverts, skysphere_element3i, skysphere_numtriangles * 3, 0);
pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHABLENDENABLE, TRUE);
// pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHATESTENABLE, TRUE);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG2, D3DTA_CURRENT);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
// pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
// qglTranslatef(time*8/128, time*8/128, 0);
d3d_animateskysphere(time*16/128);
pD3DDev->lpVtbl->SetTexture(pD3DDev, 0, (LPDIRECTDRAWSURFACE7)alphaskytexture);
pD3DDev->lpVtbl->DrawIndexedPrimitive(pD3DDev, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_TEX1, skysphere_d3dvertex, skysphere_numverts, skysphere_element3i, skysphere_numtriangles * 3, 0);
pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE);
// qglDisable(GL_BLEND);
// qglPopMatrix();
// qglMatrixMode(GL_MODELVIEW);
}
// qglPopMatrix();
/*
if (!cls.allow_skyboxes) //allow a little extra fps.
{//Draw the texture chain to only the depth buffer.
if (qglColorMask)
qglColorMask(0,0,0,0);
for (; fa; fa = fa->texturechain)
{
GL_DrawAliasMesh(fa->mesh, 0);
}
if (qglColorMask)
qglColorMask(1,1,1,1);
}
*/
}
void D3D9_DrawSkySphere (msurface_t *fa)
{
extern cvar_t gl_maxdist;
float time = cl.gametime+realtime-cl.gametimemark;
float skydist = 99999;//gl_maxdist.value;
if (skydist<1)
skydist=gl_skyboxdist.value;
skydist/=16;
//scale sky sphere and place around view origin.
// qglPushMatrix();
// qglTranslatef(r_refdef.vieworg[0], r_refdef.vieworg[1], r_refdef.vieworg[2]);
// qglScalef(skydist, skydist, skydist);
//draw in bulk? this is eeevil
//FIXME: We should use the skybox clipping code and split the sphere into 6 sides.
/*#ifdef Q3SHADERS
if (fa->texinfo->texture->shader)
{ //the shader route.
meshbuffer_t mb;
d3d_skyspherecalc(2);
mb.sortkey = 0;
mb.infokey = -1;
mb.dlightbits = 0;
mb.entity = &r_worldentity;
mb.shader = fa->texinfo->texture->shader;
mb.fog = NULL;
mb.mesh = &skymesh;
R_PushMesh(mb.mesh, mb.shader->features);
R_RenderMeshBuffer(&mb, false);
}
else
#endif*/
{ //the boring route.
d3d_skyspherecalc(1);
// qglMatrixMode(GL_TEXTURE);
// qglPushMatrix();
// qglTranslatef(time*8/128, time*8/128, 0);
d3d_animateskysphere(time*8/128);
D3D9_DrawSkyMesh(0, solidskytexture, skysphere_d3dvertex, skysphere_numverts, skysphere_element3i, skysphere_numtriangles);
d3d_animateskysphere(time*16/128);
D3D9_DrawSkyMesh(1, alphaskytexture, skysphere_d3dvertex, skysphere_numverts, skysphere_element3i, skysphere_numtriangles);
// qglDisable(GL_BLEND);
// qglPopMatrix();
// qglMatrixMode(GL_MODELVIEW);
}
// qglPopMatrix();
/*
if (!cls.allow_skyboxes) //allow a little extra fps.
{//Draw the texture chain to only the depth buffer.
if (qglColorMask)
qglColorMask(0,0,0,0);
for (; fa; fa = fa->texturechain)
{
GL_DrawAliasMesh(fa->mesh, 0);
}
if (qglColorMask)
qglColorMask(1,1,1,1);
}
*/
}
#endif
/*
==============
@ -801,8 +1186,8 @@ void R_ForceSkyBox (void)
}
}
void MakeSkyVec (float s, float t, int axis)
#ifdef RGLQUAKE
void GL_MakeSkyVec (float s, float t, int axis)
{
vec3_t v, b;
int j, k;
@ -842,6 +1227,7 @@ void MakeSkyVec (float s, float t, int axis)
qglTexCoord2f (s, t);
qglVertex3fv (v);
}
#endif
/*
==============
@ -849,7 +1235,8 @@ R_DrawSkyBox
==============
*/
int skytexorder[6] = {0,2,1,3,4,5};
void R_DrawSkyBox (msurface_t *s)
#ifdef RGLQUAKE
void GL_DrawSkyBox (msurface_t *s)
{
msurface_t *fa;
int i;
@ -895,10 +1282,10 @@ void R_DrawSkyBox (msurface_t *s)
GL_Bind (skyboxtex[skytexorder[i]]);
qglBegin (GL_QUADS);
MakeSkyVec (skymins[0][i], skymins[1][i], i);
MakeSkyVec (skymins[0][i], skymaxs[1][i], i);
MakeSkyVec (skymaxs[0][i], skymaxs[1][i], i);
MakeSkyVec (skymaxs[0][i], skymins[1][i], i);
GL_MakeSkyVec (skymins[0][i], skymins[1][i], i);
GL_MakeSkyVec (skymins[0][i], skymaxs[1][i], i);
GL_MakeSkyVec (skymaxs[0][i], skymaxs[1][i], i);
GL_MakeSkyVec (skymaxs[0][i], skymins[1][i], i);
qglEnd ();
}
@ -916,6 +1303,7 @@ void R_DrawSkyBox (msurface_t *s)
qglColorMask(1, 1, 1, 1);
}
}
#endif
@ -928,12 +1316,12 @@ R_InitSky
A sky texture is 256*128, with the right side being a masked overlay
==============
*/
void GLR_InitSky (texture_t *mt)
void R_InitSky (texture_t *mt)
{
int i, j, p;
qbyte *src;
unsigned trans[128*128];
unsigned transpix;
unsigned transpix, alphamask;
int r, g, b;
unsigned *rgba;
char name[MAX_QPATH];
@ -964,7 +1352,7 @@ void GLR_InitSky (texture_t *mt)
Q_strlwr(name);
solidskytexture = Mod_LoadReplacementTexture(name, NULL, true, false, true);
if (!solidskytexture)
solidskytexture = GL_LoadTexture32(name, 128, 128, trans, true, false);
solidskytexture = R_LoadTexture32(name, 128, 128, trans, true, false);
/*
if (!solidskytexture)
solidskytexture = texture_extension_number++;
@ -974,7 +1362,7 @@ void GLR_InitSky (texture_t *mt)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
*/
alphamask = LittleLong(0x7fffffff);
for (i=0 ; i<128 ; i++)
for (j=0 ; j<128 ; j++)
{
@ -982,14 +1370,14 @@ void GLR_InitSky (texture_t *mt)
if (p == 0)
trans[(i*128) + j] = transpix;
else
trans[(i*128) + j] = d_8to24rgbtable[p];
trans[(i*128) + j] = d_8to24rgbtable[p] & alphamask;
}
sprintf(name, "%s_trans", mt->name);
Q_strlwr(name);
alphaskytexture = Mod_LoadReplacementTexture(name, NULL, true, true, true);
if (!alphaskytexture)
alphaskytexture = GL_LoadTexture32(name, 128, 128, trans, true, true);
alphaskytexture = R_LoadTexture32(name, 128, 128, trans, true, true);
/*
if (!alphaskytexture)
alphaskytexture = texture_extension_number++;

View file

@ -83,7 +83,6 @@ extern PFNGLPNTRIANGLESIATIPROC qglPNTrianglesiATI;
extern PFNGLPNTRIANGLESFATIPROC qglPNTrianglesfATI;
extern int texture_extension_number;
extern int texture_mode;
typedef struct {
qboolean tex_env_combine;
@ -158,7 +157,7 @@ extern int glx, gly, glwidth, glheight;
void R_TimeRefresh_f (void);
texture_t *SWR_TextureAnimation (texture_t *base);
texture_t *GLR_TextureAnimation (texture_t *base);
texture_t *R_TextureAnimation (texture_t *base);
#include "particles.h"
@ -226,6 +225,11 @@ void R_IBrokeTheArrays(void);
void R_ClearArrays (void);
#endif
int Mod_LoadReplacementTexture(char *name, char *subpath, qboolean mipmap, qboolean alpha, qboolean gammaadjust);
extern int image_width, image_height;
int Mod_LoadHiResTexture(char *name, char *subpath, qboolean mipmap, qboolean alpha, qboolean gammaadjust);
int Mod_LoadBumpmapTexture(char *name, char *subpath);
#if defined(RGLQUAKE)
void R_TranslatePlayerSkin (int playernum);
void GL_Bind (int texnum);
@ -278,10 +282,10 @@ void GL_DoSwap (void);
// gl_warp.c
//
void GL_SubdivideSurface (msurface_t *fa, float dividesize);
void EmitBothSkyLayers (msurface_t *fa);
void GL_EmitBothSkyLayers (msurface_t *fa);
void EmitWaterPolys (msurface_t *fa, float basealpha);
void EmitSkyPolys (msurface_t *fa);
void R_DrawSkyChain (msurface_t *s);
void GL_DrawSkyChain (msurface_t *s);
void R_ClearSkyBox (void);
void R_DrawSkyBox (msurface_t *s);
@ -324,7 +328,7 @@ void R_DrawGroupModel (entity_t *ent);
void GLR_MarkLights (dlight_t *light, int bit, mnode_t *node);
void GLR_MarkQ2Lights (dlight_t *light, int bit, mnode_t *node);
void GLR_AnimateLight (void);
void R_RenderDlights (void);
void GLR_RenderDlights (void);
int GLR_LightPoint (vec3_t p);
void GLQ3_LightGrid(model_t *mod, vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir);
@ -348,11 +352,8 @@ void R_DrawWorld (void);
void GL_BuildLightmaps (void);
void GL_LoadShaders(void);
int Mod_LoadReplacementTexture(char *name, char *subpath, qboolean mipmap, qboolean alpha, qboolean gammaadjust);
extern int image_width, image_height;
int Mod_LoadHiResTexture(char *name, char *subpath, qboolean mipmap, qboolean alpha, qboolean gammaadjust);
int Mod_LoadBumpmapTexture(char *name, char *subpath);
#ifndef LMBLOCK_WIDTH
#define LMBLOCK_WIDTH 128
#define LMBLOCK_HEIGHT 128
typedef struct glRect_s {
@ -369,6 +370,7 @@ typedef struct {
qbyte deluxmaps[4*LMBLOCK_WIDTH*LMBLOCK_HEIGHT]; //fixme: make seperate structure for easy disabling with less memory usage.
stmap stainmaps[3*LMBLOCK_WIDTH*LMBLOCK_HEIGHT]; //rgb no a. added to lightmap for added (hopefully) speed.
} lightmapinfo_t;
#endif
//gl_ppl.c
void PPL_DrawWorld (void);

View file

@ -4073,7 +4073,7 @@ extern "C" {
rendererinfo_t d3drendererinfo = {
"Direct3D",
{
"d3d",
"faked3d",
"crap"
},
QR_OPENGL,
@ -4140,8 +4140,8 @@ rendererinfo_t d3drendererinfo = {
GLMod_NowLoadExternal,
GLMod_Think,
GLMod_GetTag,
GLMod_TagNumForName,
Mod_GetTag,
Mod_TagNumForName,
NULL,
D3DVID_Init,

View file

@ -1,9 +1,9 @@
#include "quakedef.h"
#if defined(RGLQUAKE) || (!defined(RGLQUAKE) && !defined(SWQUAKE))
#if defined(D3DQUAKE) || defined(RGLQUAKE) || (!defined(RGLQUAKE) && !defined(SWQUAKE))
#ifdef RUNTIMELIGHTING
#if defined(RGLQUAKE)
#if defined(RGLQUAKE) || defined(D3DQUAKE)
extern model_t *lightmodel;

View file

@ -569,6 +569,12 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
if (!isDedicated && (!qrenderer || qrenderer == -1))
{
R_RestartRenderer_f();
if (!qrenderer || qrenderer == -1)
{
Sys_Error("No renderer set when map restarted\n");
return;
}
}
#endif
@ -766,8 +772,8 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
}
sv.state = ss_loading;
sv.worldmodel = Mod_ForName (sv.modelname, true);
if (sv.worldmodel->needload)
Sys_Error("%s is missing\n", sv.modelname);
if (!sv.worldmodel || sv.worldmodel->needload)
Sys_Error("%s is missing or corrupt\n", sv.modelname);
if (sv.worldmodel->type != mod_brush && sv.worldmodel->type != mod_heightmap)
Sys_Error("%s is not a bsp model\n", sv.modelname);
sv.state = ss_dead;

View file

@ -233,13 +233,16 @@ void R_SetupAndDrawSprite ()
R_GetSpriteframe
================
*/
mspriteframe_t *R_GetSpriteframe (msprite_t *psprite)
/*
mspriteframe_t *R_GetSpriteFrame (entity_t *currententity)
{
msprite_t *psprite;
mspritegroup_t *pspritegroup;
mspriteframe_t *pspriteframe;
int i, numframes, frame;
float *pintervals, fullinterval, targettime, time;
psprite = currententity->model->cache.data;
frame = currententity->frame;
if ((frame >= psprite->numframes) || (frame < 0))
@ -276,7 +279,7 @@ mspriteframe_t *R_GetSpriteframe (msprite_t *psprite)
return pspriteframe;
}
*/
/*
================
@ -292,7 +295,7 @@ void R_DrawSprite (void)
psprite = currententity->model->cache.data;
r_spritedesc.pspriteframe = R_GetSpriteframe (psprite);
r_spritedesc.pspriteframe = R_GetSpriteFrame (currententity);
sprite_width = r_spritedesc.pspriteframe->width;
sprite_height = r_spritedesc.pspriteframe->height;