1
0
Fork 0
forked from fte/fteqw

lots of useless stuff.

will attempt to load doom3 maps.
_gl_fog 1 and friends can be used to activate fog, still needs tweeks for use, not a final feature at all.
added gl_screenangle which rotates the screen, including hud.
seems to be some nvidia driver issue. may need end-tasking after video shuts down (including from-fullscreen vid_restarts).
double-frees on glsl shaders is now supposedly fixed.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3735 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2011-02-25 04:22:14 +00:00
parent 40a18f65bb
commit 946b5d6f52
43 changed files with 1036 additions and 434 deletions

View file

@ -67,14 +67,21 @@ void RSpeedShow(void)
RQntNames[RQUANT_MSECS] = "Microseconds";
RQntNames[RQUANT_EPOLYS] = "Entity Polys";
RQntNames[RQUANT_WPOLYS] = "World Polys";
RQntNames[RQUANT_DRAWS] = "Draw Calls";
RQntNames[RQUANT_2DBATCHES] = "2d Batches";
RQntNames[RQUANT_WORLDBATCHES] = "World Batches";
RQntNames[RQUANT_ENTBATCHES] = "Ent Batches";
RQntNames[RQUANT_SHADOWFACES] = "Shadow Faces";
RQntNames[RQUANT_SHADOWEDGES] = "Shadow edges";
RQntNames[RQUANT_LITFACES] = "Lit faces";
for (i = 0; i < RSPEED_MAX; i++)
if (r_speeds.ival > 1)
{
s = va("%i %-20s", samplerspeeds[i], RSpNames[i]);
Draw_FunString(vid.width-strlen(s)*8, i*8, s);
for (i = 0; i < RSPEED_MAX; i++)
{
s = va("%i %-20s", samplerspeeds[i], RSpNames[i]);
Draw_FunString(vid.width-strlen(s)*8, i*8, s);
}
}
for (i = 0; i < RQUANT_MAX; i++)
{
@ -84,7 +91,7 @@ void RSpeedShow(void)
s = va("%f %-20s", 100000000.0f/samplerspeeds[RSPEED_TOTALREFRESH], "Framerate");
Draw_FunString(vid.width-strlen(s)*8, (i+RSPEED_MAX)*8, s);
if (framecount++>=100)
if (++framecount>=100)
{
for (i = 0; i < RSPEED_MAX; i++)
{
@ -1286,6 +1293,10 @@ void SCR_DrawFPS (void)
SCR_StringXY(va("%f deviation", deviation), show_fps_x.value, show_fps_y.value-8);
}
break;
case 8:
if (cls.timedemo)
Con_Printf("%f\n", frametime);
break;
}
if (usemsecs)

View file

@ -1379,7 +1379,7 @@ void Con_DrawConsole (int lines, qboolean noback)
selstartoffset = 0;
}
Draw_Fill((sstart*vid.width)/vid.pixelwidth, (y*vid.height)/vid.pixelheight, ((send - sstart)*vid.width)/vid.pixelwidth, (Font_CharHeight()*vid.height)/vid.pixelheight, 0);
Draw_Fill((sstart*vid.width)/vid.rotpixelwidth, (y*vid.height)/vid.rotpixelheight, ((send - sstart)*vid.width)/vid.rotpixelwidth, (Font_CharHeight()*vid.height)/vid.rotpixelheight, 0);
}
}
}

View file

@ -2124,7 +2124,7 @@ texid_t GL_LoadTextureDDS(unsigned char *buffer, int filesize)
return r_nulltex;
texnum = GL_AllocNewTexture(fmtheader.dwWidth, fmtheader.dwHeight);
GL_Bind(texnum);
GL_MTBind(0, GL_TEXTURE_2D, texnum);
datasize = fmtheader.dwPitchOrLinearSize;
for (mipnum = 0; mipnum < nummips; mipnum++)

View file

@ -2039,7 +2039,7 @@ static int MSD_GetDMAPos(soundcardinfo_t *sc)
return s;
}
static void MSD_Submit(soundcardinfo_t *sc)
static void MSD_Submit(soundcardinfo_t *sc, int start, int end)
{
//Fixme: support outputting to wav
//http://www.borg.com/~jglatt/tech/wave.htm

View file

@ -168,9 +168,10 @@ typedef enum backendmode_e
BEM_DEPTHONLY, //just a quick depth pass. textures used only for alpha test (shadowmaps).
BEM_STENCIL, //used for drawing shadow volumes to the stencil buffer.
BEM_DEPTHDARK, //a quick depth pass. textures used only for alpha test. additive textures still shown as normal.
BEM_LIGHT, //we have a valid light
BEM_LIGHT, //we have a valid light
BEM_SMAPLIGHTSPOT, //we have a spot light using a shadowmap
BEM_SMAPLIGHT //we have a light using a shadowmap
BEM_SMAPLIGHT, //we have a light using a shadowmap
BEM_FOG //drawing a fog volume
} backendmode_t;
typedef struct rendererinfo_s {

View file

@ -1433,7 +1433,7 @@ static void P_ImportEffectInfo_f(void)
Con_Printf("Too many args!\n");
args--;
}
line = COM_StringParse(line, false, false);
line = COM_StringParse(line, com_token, sizeof(com_token), false, false);
Q_strncpyz(arg[args], com_token, sizeof(arg[args]));
args++;
if (*com_token == '\n')

View file

@ -704,8 +704,8 @@ static void QCBUILTIN PF_cs_makestatic (progfuncs_t *prinst, struct globalvars_s
ent = &cl_static_entities[cl.num_statics].ent;
if (CopyCSQCEdictToEntity(in, ent))
{
cl.num_statics++;
cl_static_entities[cl.num_statics].mdlidx = in->v->modelindex;
cl.num_statics++;
}
PF_cs_remove(prinst, pr_globals);

View file

@ -22,11 +22,13 @@ extern cvar_t scr_conalpha;
extern cvar_t gl_conback;
extern cvar_t gl_font;
extern cvar_t gl_contrast;
extern cvar_t gl_screenangle;
extern cvar_t vid_conautoscale;
extern cvar_t vid_conheight;
extern cvar_t vid_conwidth;
void R2D_Font_Callback(struct cvar_s *var, char *oldvalue);
void R2D_Conautoscale_Callback(struct cvar_s *var, char *oldvalue);
void R2D_ScreenAngle_Callback(struct cvar_s *var, char *oldvalue);
void R2D_Conheight_Callback(struct cvar_s *var, char *oldvalue);
void R2D_Conwidth_Callback(struct cvar_s *var, char *oldvalue);
@ -128,6 +130,7 @@ void R2D_Init(void)
Cvar_Hook(&gl_font, R2D_Font_Callback);
Cvar_Hook(&vid_conautoscale, R2D_Conautoscale_Callback);
Cvar_Hook(&gl_screenangle, R2D_ScreenAngle_Callback);
Cvar_Hook(&vid_conheight, R2D_Conheight_Callback);
Cvar_Hook(&vid_conwidth, R2D_Conwidth_Callback);
@ -383,9 +386,9 @@ void R2D_Font_Callback(struct cvar_s *var, char *oldvalue)
return;
}
font_conchar = Font_LoadFont(8*vid.pixelheight/vid.height, var->string);
font_conchar = Font_LoadFont(8*vid.rotpixelheight/vid.height, var->string);
if (!font_conchar && *var->string)
font_conchar = Font_LoadFont(8*vid.pixelheight/vid.height, "");
font_conchar = Font_LoadFont(8*vid.rotpixelheight/vid.height, "");
}
// console size manipulation callbacks
@ -396,6 +399,23 @@ void R2D_Console_Resize(void)
int cwidth, cheight;
float xratio;
float yratio=0;
float ang, rad;
extern cvar_t gl_screenangle;
ang = (gl_screenangle.value>0?(gl_screenangle.value+45):(gl_screenangle.value-45))/90;
ang = (int)ang * 90;
if (ang)
{
rad = (ang * M_PI) / 180;
vid.rotpixelwidth = fabs(cos(rad)) * (vid.pixelwidth) + fabs(sin(rad)) * (vid.pixelheight);
vid.rotpixelheight = fabs(sin(rad)) * (vid.pixelwidth) + fabs(cos(rad)) * (vid.pixelheight);
}
else
{
vid.rotpixelwidth = vid.pixelwidth;
vid.rotpixelheight = vid.pixelheight;
}
cwidth = vid_conwidth.value;
cheight = vid_conheight.value;
@ -413,8 +433,8 @@ void R2D_Console_Resize(void)
yratio = 1 / yratio;
//autoscale overrides conwidth/height (without actually changing them)
cwidth = vid.pixelwidth;
cheight = vid.pixelheight;
cwidth = vid.rotpixelwidth;
cheight = vid.rotpixelheight;
}
else
{
@ -424,9 +444,9 @@ void R2D_Console_Resize(void)
if (!cwidth)
cwidth = vid.pixelwidth;
cwidth = vid.rotpixelwidth;
if (!cheight)
cheight = vid.pixelheight;
cheight = vid.rotpixelheight;
cwidth*=xratio;
cheight*=yratio;
@ -493,6 +513,11 @@ void R2D_Conautoscale_Callback(struct cvar_s *var, char *oldvalue)
R2D_Console_Resize();
}
void R2D_ScreenAngle_Callback(struct cvar_s *var, char *oldvalue)
{
R2D_Console_Resize();
}
/*
============

View file

@ -1870,6 +1870,11 @@ void Surf_SetupFrame(void)
}
}
#endif
else if (cl.worldmodel && cl.worldmodel->fromgame == fg_doom3)
{
r_viewleaf = NULL;
r_viewleaf2 = NULL;
}
else
{
r_oldviewleaf = r_viewleaf;
@ -1945,7 +1950,7 @@ void Surf_GenBrushBatches(batch_t **batches, entity_t *ent)
// calculate dynamic lighting for bmodel if it's not an
// instanced model
if (model->fromgame != fg_quake3)
if (model->fromgame != fg_quake3 && model->fromgame != fg_doom3)
{
int k;
int shift;
@ -2001,6 +2006,36 @@ void Surf_GenBrushBatches(batch_t **batches, entity_t *ent)
if (ent->flags & RF_NODEPTHTEST)
bef |= BEF_FORCENODEPTH;
if (!model->surfaces && model->batches)
{
for (i = 0; i < model->numsurfaces; i++)
{
b = BE_GetTempBatch();
if (!b)
continue;
*b = model->batches[0][i];
b->mesh = (mesh_t**)&model->batches[0][i].mesh;
b->ent = ent;
if (bef & BEF_FORCEADDITIVE)
{
b->next = batches[SHADER_SORT_ADDITIVE];
batches[SHADER_SORT_ADDITIVE] = b;
}
else if (bef & BEF_FORCETRANSPARENT)
{
b->next = batches[SHADER_SORT_BLEND];
batches[SHADER_SORT_BLEND] = b;
}
else
{
b->next = batches[b->shader->sort];
batches[b->shader->sort] = b;
}
}
return;
}
b = NULL;
for (s = model->surfaces+model->firstmodelsurface,i = 0; i < model->nummodelsurfaces; i++, s++)
{
@ -2117,6 +2152,11 @@ void Surf_DrawWorld (void)
}
else
#endif
if (cl.worldmodel->fromgame == fg_doom3)
{
vis = D3_CalcVis(cl.worldmodel, r_refdef.vieworg);
}
else
{
//extern cvar_t temp1;
if (0)//temp1.value)
@ -2155,7 +2195,7 @@ void Surf_DrawWorld (void)
*/
// returns a texture number and the position inside it
static int Surf_LM_AllocBlock (int w, int h, int *x, int *y)
static int Surf_LM_AllocBlock (int w, int h, int *x, int *y, shader_t *shader)
{
int i, j;
int best, best2;
@ -2189,6 +2229,7 @@ static int Surf_LM_AllocBlock (int w, int h, int *x, int *y)
lightmap[texnum] = Z_Malloc(sizeof(*lightmap[texnum]));
lightmap[texnum]->meshchain = NULL;
lightmap[texnum]->modified = true;
lightmap[texnum]->shader = shader;
// reset stainmap since it now starts at 255
memset(lightmap[texnum]->stainmaps, 255, sizeof(lightmap[texnum]->stainmaps));
@ -2201,6 +2242,9 @@ static int Surf_LM_AllocBlock (int w, int h, int *x, int *y)
}
}
/*not required, but using one lightmap per texture can result in better texture unit switching*/
if (lightmap[texnum]->shader != shader)
continue;
best = LMBLOCK_HEIGHT;
@ -2445,7 +2489,7 @@ static void Surf_CreateSurfaceLightmap (msurface_t *surf, int shift)
if (currentmodel->fromgame == fg_quake3)
Surf_LM_FillBlock(surf->lightmaptexturenum, smax, tmax, surf->light_s, surf->light_t);
else
surf->lightmaptexturenum = Surf_LM_AllocBlock (smax, tmax, &surf->light_s, &surf->light_t);
surf->lightmaptexturenum = Surf_LM_AllocBlock (smax, tmax, &surf->light_s, &surf->light_t, surf->texinfo->texture->shader);
base = lightmap[surf->lightmaptexturenum]->lightmaps;
base += (surf->light_t * LMBLOCK_WIDTH + surf->light_s) * lightmap_bytes;
@ -2490,6 +2534,8 @@ void Surf_Clear(model_t *mod)
{
batch_t *b;
int i;
if (mod->fromgame == fg_doom3)
return;/*they're on the hunk*/
for (i = 0; i < SHADER_SORT_COUNT; i++)
{
while ((b = mod->batches[i]))

View file

@ -199,6 +199,7 @@ typedef struct {
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.
shader_t *shader;
} lightmapinfo_t;
extern lightmapinfo_t **lightmap;
extern int numlightmaps;
@ -460,6 +461,10 @@ enum {
RQUANT_MSECS, //old r_speeds
RQUANT_EPOLYS,
RQUANT_WPOLYS,
RQUANT_DRAWS,
RQUANT_ENTBATCHES,
RQUANT_WORLDBATCHES,
RQUANT_2DBATCHES,
RQUANT_SHADOWFACES,
RQUANT_SHADOWEDGES,
RQUANT_LITFACES,
@ -468,7 +473,7 @@ enum {
};
int rquant[RQUANT_MAX];
#define RQuantAdd(type,quant) rquant[type] += quant;
#define RQuantAdd(type,quant) rquant[type] += quant
#if defined(NDEBUG) || !defined(_WIN32)
#define RSpeedLocals()
@ -477,13 +482,13 @@ int rquant[RQUANT_MAX];
#define RSpeedEnd(spt)
#else
#define RSpeedLocals() int rsp
#define RSpeedMark() int rsp = r_speeds.ival?Sys_DoubleTime()*1000000:0
#define RSpeedRemark() rsp = r_speeds.ival?Sys_DoubleTime()*1000000:0
#define RSpeedMark() int rsp = (r_speeds.ival>1)?Sys_DoubleTime()*1000000:0
#define RSpeedRemark() rsp = (r_speeds.ival>1)?Sys_DoubleTime()*1000000:0
#if defined(_WIN32) && defined(GLQUAKE)
extern void (_stdcall *qglFinish) (void);
#define RSpeedEnd(spt) do {if(r_speeds.ival && qglFinish){qglFinish(); rspeeds[spt] += (int)(Sys_DoubleTime()*1000000) - rsp;}}while (0)
#define RSpeedEnd(spt) do {if(r_speeds.ival > 1){if(r_speeds.ival > 2 && qglFinish)qglFinish(); rspeeds[spt] += (int)(Sys_DoubleTime()*1000000) - rsp;}}while (0)
#else
#define RSpeedEnd(spt) rspeeds[spt] += r_speeds.value?Sys_DoubleTime()*1000000 - rsp:0
#define RSpeedEnd(spt) rspeeds[spt] += (r_speeds.ival>1)?Sys_DoubleTime()*1000000 - rsp:0
#endif
#endif

View file

@ -339,6 +339,7 @@ cvar_t vid_desktopgamma = SCVARF ("vid_desktopgamma", "0",
CVAR_ARCHIVE | CVAR_RENDERERLATCH);
extern cvar_t gl_dither;
cvar_t gl_screenangle = SCVAR("gl_screenangle", "0");
#endif
@ -435,6 +436,8 @@ void GLRenderer_Init(void)
Cvar_Register (&gl_ati_truform_type, GRAPHICALNICETIES);
Cvar_Register (&gl_ati_truform_tesselation, GRAPHICALNICETIES);
Cvar_Register (&gl_screenangle, GLRENDEREROPTIONS);
Cvar_Register (&gl_skyboxdist, GLRENDEREROPTIONS);
Cvar_Register (&r_wallcolour, GLRENDEREROPTIONS);

View file

@ -188,7 +188,7 @@ void Draw_FunStringWidth(int x, int y, const void *str, int width)
conchar_t buffer[2048];
conchar_t *w = buffer;
width = (width*vid.pixelwidth)/vid.width;
width = (width*vid.rotpixelwidth)/vid.width;
COM_ParseFunString(CON_WHITEMASK, str, buffer, sizeof(buffer), false);

View file

@ -52,13 +52,15 @@ typedef struct
pixel_t *colormap; // 256 * VID_GRADES size
int fullbright; // index of first fullbright color
unsigned width;
unsigned height;
unsigned width; /*virtual 2d width*/
unsigned height; /*virtual 2d height*/
int numpages;
int recalc_refdef; // if true, recalc vid-based stuff
unsigned pixelwidth;
unsigned pixelheight;
unsigned rotpixelwidth; /*width after rotation in pixels*/
unsigned rotpixelheight; /*pixel after rotation in pixels*/
unsigned pixelwidth; /*true height in pixels*/
unsigned pixelheight; /*true width in pixels*/
} viddef_t;
extern viddef_t vid; // global video state

View file

@ -1159,7 +1159,7 @@ void SCR_VRectForPlayer(vrect_t *vrect, int pnum)
case 2: //horizontal bands
case 3:
#ifdef GLQUAKE
if (qrenderer == QR_OPENGL && vid.pixelwidth > vid.pixelheight * 2
if (qrenderer == QR_OPENGL && vid.rotpixelwidth > vid.rotpixelheight * 2
#ifdef FISH
&& ffov.value >= 0
#endif

View file

@ -160,7 +160,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define HUFFNETWORK //huffman network compression
//#define DOOMWADS //doom wad/sprite support
//#define MAP_DOOM //doom map support
//#define MAP_PROC //doom3/quake4 map support
#define MAP_PROC //doom3/quake4 map support
//#define WOLF3DSUPPORT //wolfenstein3d map support (not started yet)
#define Q2BSPS //quake 2 bsp support
#define Q3BSPS //quake 3 bsp support

View file

@ -1086,7 +1086,7 @@ void Cmd_ShiftArgs (int ammount, qboolean expandstring)
if (cmd_args)
{
cmd_args = COM_StringParse(cmd_args, expandstring, false);
cmd_args = COM_StringParse(cmd_args, com_token, sizeof(com_token), expandstring, false);
if (cmd_args)
while(*cmd_args == ' ' || *cmd_args == '\t')
cmd_args++;
@ -1372,7 +1372,7 @@ void Cmd_TokenizeString (char *text, qboolean expandmacros, qboolean qctokenize)
Cmd_Args_Set(text);
}
text = COM_StringParse (text, expandmacros, qctokenize);
text = COM_StringParse (text, com_token, sizeof(com_token), expandmacros, qctokenize);
if (!text)
return;

View file

@ -2425,6 +2425,21 @@ skipwhite:
}
}
//skip / * comments
if (c == '/' && data[1] == '*')
{
data+=2;
while(*data)
{
if (*data == '*' && data[1] == '/')
{
data+=2;
goto skipwhite;
}
data++;
}
goto skipwhite;
}
// handle quoted strings specially
if (c == '\"')
@ -2469,14 +2484,14 @@ skipwhite:
}
//same as COM_Parse, but parses two quotes next to each other as a single quote as part of the string
char *COM_StringParse (const char *data, qboolean expandmacros, qboolean qctokenize)
char *COM_StringParse (const char *data, char *token, unsigned int tokenlen, qboolean expandmacros, qboolean qctokenize)
{
int c;
int len;
char *s;
len = 0;
com_token[0] = 0;
token[0] = 0;
if (!data)
return NULL;
@ -2491,8 +2506,8 @@ skipwhite:
}
if (c == '\n')
{
com_token[len++] = c;
com_token[len] = 0;
token[len++] = c;
token[len] = 0;
return (char*)data+1;
}
@ -2530,9 +2545,9 @@ skipwhite:
data++;
while (1)
{
if (len >= TOKENSIZE-1)
if (len >= tokenlen-1)
{
com_token[len] = '\0';
token[len] = '\0';
return (char*)data;
}
@ -2543,12 +2558,12 @@ skipwhite:
c = *(data);
if (c!='\"')
{
com_token[len] = 0;
token[len] = 0;
return (char*)data;
}
while (c=='\"')
{
com_token[len] = c;
token[len] = c;
len++;
data++;
c = *(data+1);
@ -2556,10 +2571,10 @@ skipwhite:
}
if (!c)
{
com_token[len] = 0;
token[len] = 0;
return (char*)data-1;
}
com_token[len] = c;
token[len] = c;
len++;
}
}
@ -2570,9 +2585,9 @@ skipwhite:
data++;
while (1)
{
if (len >= TOKENSIZE-1)
if (len >= tokenlen-1)
{
com_token[len] = '\0';
token[len] = '\0';
return (char*)data;
}
@ -2583,12 +2598,12 @@ skipwhite:
c = *(data);
if (c!='\'')
{
com_token[len] = 0;
token[len] = 0;
return (char*)data;
}
while (c=='\'')
{
com_token[len] = c;
token[len] = c;
len++;
data++;
c = *(data+1);
@ -2596,10 +2611,10 @@ skipwhite:
}
if (!c)
{
com_token[len] = 0;
token[len] = 0;
return (char*)data;
}
com_token[len] = c;
token[len] = c;
len++;
}
}
@ -2607,33 +2622,33 @@ skipwhite:
if (qctokenize && (c == '\n' || c == '{' || c == '}' || c == ')' || c == '(' || c == ']' || c == '[' || c == '\'' || c == ':' || c == ',' || c == ';'))
{
// single character
com_token[len++] = c;
com_token[len] = 0;
token[len++] = c;
token[len] = 0;
return (char*)data+1;
}
// parse a regular word
do
{
if (len >= TOKENSIZE-1)
if (len >= tokenlen-1)
{
com_token[len] = '\0';
token[len] = '\0';
return (char*)data;
}
com_token[len] = c;
token[len] = c;
data++;
len++;
c = *data;
} while ((unsigned)c>32 && !(qctokenize && (c == '\n' || c == '{' || c == '}' || c == ')' || c == '(' || c == ']' || c == '[' || c == '\'' || c == ':' || c == ',' || c == ';')));
com_token[len] = 0;
token[len] = 0;
if (!expandmacros)
return (char*)data;
//now we check for macros.
for (s = com_token, c= 0; c < len; c++, s++) //this isn't a quoted token by the way.
for (s = token, c= 0; c < len; c++, s++) //this isn't a quoted token by the way.
{
if (*s == '$')
{
@ -2653,9 +2668,9 @@ skipwhite:
macro = Cvar_FindVar(name);
if (macro) //got one...
{
if (len+strlen(macro->string)-(i+1) >= TOKENSIZE-1) //give up.
if (len+strlen(macro->string)-(i+1) >= tokenlen-1) //give up.
{
com_token[len] = '\0';
token[len] = '\0';
return (char*)data;
}
memmove(s+strlen(macro->string), s+i+1, len-c-i);

View file

@ -249,7 +249,7 @@ extern qboolean com_eof;
char *COM_ParseOut (const char *data, char *out, int outlen);
char *COM_ParseStringSet (const char *data);
char *COM_ParseCString (const char *data);
char *COM_StringParse (const char *data, qboolean expandmacros, qboolean qctokenize);
char *COM_StringParse (const char *data, char *token, unsigned int tokenlen, qboolean expandmacros, qboolean qctokenize);
char *COM_ParseToken (const char *data, const char *punctuation);
char *COM_TrimString(char *str);

View file

@ -898,7 +898,10 @@ vfsfile_t *FS_OpenVFS(const char *filename, const char *mode, enum fs_relative r
//if we're meant to be writing, best write to it.
if (strchr(mode , 'w') || strchr(mode , 'a'))
{
COM_CreatePath(fullname);
return VFSOS_Open(fullname, mode);
}
return NULL;
}

View file

@ -1986,7 +1986,7 @@ int tokenizeqc(char *str, qboolean dpfuckage)
break;
qctoken[qctoken_count].start = str - start;
str = COM_StringParse (str, false, dpfuckage);
str = COM_StringParse (str, com_token, sizeof(com_token), false, dpfuckage);
if (!str)
break;

View file

@ -714,9 +714,9 @@ void Netchan_TransmitNextFragment( netchan_t *chan )
NET_SendPacket( chan->sock, send.cursize, send.data, chan->remote_address );
// if( net_showpackets->integer )
{
Con_Printf( "%s send %4i : s=%i fragment=%i,%i\n", (chan->sock == NS_CLIENT) ? "client" : "server", send.cursize, chan->outgoing_sequence, chan->reliable_start, fragmentLength );
}
// {
// Con_Printf( "%s send %4i : s=%i fragment=%i,%i\n", (chan->sock == NS_CLIENT) ? "client" : "server", send.cursize, chan->outgoing_sequence, chan->reliable_start, fragmentLength );
// }
// Even if we have sent the whole message,
// but if fragmentLength == FRAGMENTATION_TRESHOLD we have to write empty

View file

@ -2179,7 +2179,7 @@ static void BE_SubmitMeshesSortList(batch_t *sortlist)
if (batch->buildmeshes)
batch->buildmeshes(batch);
else
else if (batch->texture)
{
batch->shader = R_TextureAnimation(batch->ent->framestate.g[FS_REG].frame[0], batch->texture)->shader;
batch->skin = &batch->shader->defaulttextures;

View file

@ -3,6 +3,8 @@
#include "shader.h"
#include "renderque.h"
#include "glquake.h"
#ifdef D3DQUAKE
#include "winquake.h"
@ -733,6 +735,9 @@ static void (D3D9_R_NewMap) (void)
R_AnimateLight();
Surf_BuildLightmaps();
if (cl.worldmodel && cl.worldmodel->fromgame == fg_doom3)
D3_GenerateAreas(cl.worldmodel);
/*wipe any lingering particles*/
P_ClearParticles();
}

View file

@ -320,7 +320,7 @@ static const char PCFPASS_SHADER[] = "\
extern cvar_t r_glsl_offsetmapping, r_noportals;
static void BE_SendPassBlendAndDepth(unsigned int sbits);
static void BE_SendPassBlendDepthMask(unsigned int sbits);
void GLBE_SubmitBatch(batch_t *batch);
struct {
@ -342,6 +342,8 @@ struct {
int currenttmu;
int texenvmode[SHADER_PASS_MAX];
int currenttextures[SHADER_PASS_MAX];
GLenum curtexturetype[SHADER_PASS_MAX];
unsigned int tmuarrayactive;
polyoffset_t curpolyoffset;
unsigned int curcull;
@ -367,6 +369,8 @@ struct {
float identitylighting; //set to how bright lightmaps should be (reduced for overbright or realtime_world_lightmaps)
texid_t temptexture;
texid_t fogtexture;
float fogfar;
};
//exterior state (paramters)
@ -434,11 +438,8 @@ void GL_SetShaderState2D(qboolean is2d)
void GL_SelectTexture(int target)
{
shaderstate.currenttmu = target;
if (qglClientActiveTextureARB)
{
qglClientActiveTextureARB(target + mtexid0);
if (qglActiveTextureARB)
qglActiveTextureARB(target + mtexid0);
}
else if (qglSelectTextureSGIS)
qglSelectTextureSGIS(target + mtexid0);
}
@ -477,40 +478,83 @@ static void GL_ApplyVertexPointer(void)
}
}
void GL_MBind(int target, texid_t texnum)
void GL_MTBind(int tmu, int target, texid_t texnum)
{
GL_SelectTexture(target);
GL_SelectTexture(tmu);
#ifndef FORCESTATE
if (shaderstate.currenttextures[shaderstate.currenttmu] == texnum.num)
if (shaderstate.currenttextures[tmu] == texnum.num)
return;
#endif
shaderstate.currenttextures[shaderstate.currenttmu] = texnum.num;
bindTexFunc (GL_TEXTURE_2D, texnum.num);
shaderstate.currenttextures[tmu] = texnum.num;
if (target)
bindTexFunc (target, texnum.num);
if (shaderstate.curtexturetype[tmu] != target)
{
if (shaderstate.curtexturetype[tmu])
qglDisable(shaderstate.curtexturetype[tmu]);
shaderstate.curtexturetype[tmu] = target;
if (target)
qglEnable(target);
}
if (((shaderstate.tmuarrayactive>>tmu) & 1) != 0)
{
qglClientActiveTextureARB(tmu + mtexid0);
if (0)
{
shaderstate.tmuarrayactive |= 1u<<tmu;
qglEnableClientState(GL_TEXTURE_COORD_ARRAY);
}
else
{
shaderstate.tmuarrayactive &= ~(1u<<tmu);
qglDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
}
}
void GL_Bind(texid_t texnum)
void GL_LazyBind(int tmu, int target, texid_t texnum, qboolean arrays)
{
#ifndef FORCESTATE
if (shaderstate.currenttextures[shaderstate.currenttmu] == texnum.num)
return;
if (shaderstate.currenttextures[tmu] != texnum.num)
#endif
{
GL_SelectTexture(tmu);
shaderstate.currenttextures[shaderstate.currenttmu] = texnum.num;
shaderstate.currenttextures[shaderstate.currenttmu] = texnum.num;
if (target)
bindTexFunc (target, texnum.num);
bindTexFunc (GL_TEXTURE_2D, texnum.num);
}
if (shaderstate.curtexturetype[tmu] != target)
{
if (shaderstate.curtexturetype[tmu])
qglDisable(shaderstate.curtexturetype[tmu]);
shaderstate.curtexturetype[tmu] = target;
if (target)
qglEnable(target);
}
}
void GL_BindType(int type, texid_t texnum)
{
#ifndef FORCESTATE
if (shaderstate.currenttextures[shaderstate.currenttmu] == texnum.num)
return;
#endif
if (!target)
arrays = false;
shaderstate.currenttextures[shaderstate.currenttmu] = texnum.num;
bindTexFunc (type, texnum.num);
if (((shaderstate.tmuarrayactive>>tmu) & 1) != arrays)
{
qglClientActiveTextureARB(mtexid0 + tmu);
if (arrays)
{
shaderstate.tmuarrayactive |= 1u<<tmu;
qglEnableClientState(GL_TEXTURE_COORD_ARRAY);
}
else
{
shaderstate.tmuarrayactive &= ~(1u<<tmu);
qglDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
}
}
static void BE_EnableShaderAttributes(unsigned int newm)
@ -642,9 +686,7 @@ static void RevertToKnownState(void)
while(shaderstate.lastpasstmus>0)
{
GL_SelectTexture(--shaderstate.lastpasstmus);
qglDisable(GL_TEXTURE_2D);
qglDisableClientState(GL_TEXTURE_COORD_ARRAY);
GL_LazyBind(--shaderstate.lastpasstmus, 0, r_nulltex, false);
}
GL_SelectTexture(0);
@ -654,7 +696,7 @@ static void RevertToKnownState(void)
qglColor3f(1,1,1);
shaderstate.shaderbits &= ~(SBITS_MISC_DEPTHEQUALONLY|SBITS_MISC_DEPTHCLOSERONLY);
shaderstate.shaderbits &= ~(SBITS_MISC_DEPTHEQUALONLY|SBITS_MISC_DEPTHCLOSERONLY|SBITS_MASK_BITS);
shaderstate.shaderbits |= SBITS_MISC_DEPTHWRITE;
shaderstate.shaderbits &= ~(SBITS_BLEND_BITS);
@ -695,12 +737,9 @@ void BE_SetupForShadowMap(void)
{
while(shaderstate.lastpasstmus>0)
{
GL_SelectTexture(--shaderstate.lastpasstmus);
qglDisable(GL_TEXTURE_2D);
qglDisableClientState(GL_TEXTURE_COORD_ARRAY);
GL_LazyBind(--shaderstate.lastpasstmus, 0, r_nulltex, false);
}
qglDisableClientState(GL_TEXTURE_COORD_ARRAY);
qglShadeModel(GL_FLAT);
GL_TexEnv(GL_REPLACE);
qglDepthMask(GL_TRUE);
@ -711,7 +750,7 @@ void BE_SetupForShadowMap(void)
}
#endif
static texid_t T_Gen_CurrentRender(void)
static void T_Gen_CurrentRender(int tmu)
{
int vwidth, vheight;
if (gl_config.arb_texture_non_power_of_two)
@ -735,51 +774,69 @@ static texid_t T_Gen_CurrentRender(void)
// copy the scene to texture
if (!TEXVALID(shaderstate.temptexture))
shaderstate.temptexture = GL_AllocNewTexture(vwidth, vheight);
GL_Bind(shaderstate.temptexture);
GL_MTBind(tmu, GL_TEXTURE_2D, shaderstate.temptexture);
qglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, vwidth, vheight, 0);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
return shaderstate.temptexture;
}
static texid_t Shader_TextureForPass(const shaderpass_t *pass)
static void Shader_BindTextureForPass(int tmu, const shaderpass_t *pass, qboolean useclientarray)
{
texid_t t;
switch(pass->texgen)
{
default:
case T_GEN_SKYBOX:
t = pass->anim_frames[0];
GL_LazyBind(tmu, GL_TEXTURE_CUBE_MAP_ARB, t, useclientarray);
return;
case T_GEN_SINGLEMAP:
return pass->anim_frames[0];
t = pass->anim_frames[0];
break;
case T_GEN_ANIMMAP:
return pass->anim_frames[(int)(pass->anim_fps * shaderstate.curtime) % pass->anim_numframes];
t = pass->anim_frames[(int)(pass->anim_fps * shaderstate.curtime) % pass->anim_numframes];
break;
case T_GEN_LIGHTMAP:
return shaderstate.curlightmap;
t = shaderstate.curlightmap;
break;
case T_GEN_DELUXMAP:
return shaderstate.curdeluxmap;
t = shaderstate.curdeluxmap;
break;
case T_GEN_DIFFUSE:
return shaderstate.curtexnums?shaderstate.curtexnums->base:r_nulltex;
t = shaderstate.curtexnums?shaderstate.curtexnums->base:r_nulltex;
break;
case T_GEN_NORMALMAP:
return shaderstate.curtexnums?shaderstate.curtexnums->bump:r_nulltex;
t = shaderstate.curtexnums?shaderstate.curtexnums->bump:r_nulltex;
break;
case T_GEN_SPECULAR:
return shaderstate.curtexnums->specular;
t = shaderstate.curtexnums->specular;
break;
case T_GEN_UPPEROVERLAY:
return shaderstate.curtexnums->upperoverlay;
t = shaderstate.curtexnums->upperoverlay;
break;
case T_GEN_LOWEROVERLAY:
return shaderstate.curtexnums->loweroverlay;
t = shaderstate.curtexnums->loweroverlay;
break;
case T_GEN_FULLBRIGHT:
return shaderstate.curtexnums->fullbright;
t = shaderstate.curtexnums->fullbright;
break;
case T_GEN_SHADOWMAP:
return shaderstate.curshadowmap;
t = shaderstate.curshadowmap;
break;
case T_GEN_VIDEOMAP:
#ifdef NOMEDIA
return shaderstate.curtexnums?shaderstate.curtexnums->base:r_nulltex;
t = shaderstate.curtexnums?shaderstate.curtexnums->base:r_nulltex;
#else
return Media_UpdateForShader(pass->cin);
t = Media_UpdateForShader(pass->cin);
#endif
break;
case T_GEN_CURRENTRENDER:
return T_Gen_CurrentRender();
T_Gen_CurrentRender(tmu);
return;
}
GL_LazyBind(tmu, GL_TEXTURE_2D, t, useclientarray);
}
/*========================================== matrix functions =====================================*/
@ -871,11 +928,37 @@ void Shader_LightPass_Spot(char *shortname, shader_t *s, const void *args)
Shader_DefaultScript(shortname, s, shadertext);
}
texid_t GenerateFogTexture(void)
{
#define FOGS 256
#define FOGT 32
byte_vec4_t fogdata[FOGS*FOGT];
int s, t;
float f;
for(s = 0; s < FOGS; s++)
for(t = 0; t < FOGT; t++)
{
f = (float)s / FOGS;
if (f < 0)
f = 0;
if (f > 1)
f = 1;
f = pow(f, 0.5);
fogdata[t*FOGS + s][0] = 255;
fogdata[t*FOGS + s][1] = 255;
fogdata[t*FOGS + s][2] = 255;
fogdata[t*FOGS + s][3] = 255*f;
}
return R_LoadTexture32("fog", FOGS, FOGT, fogdata, IF_CLAMP|IF_NOMIPMAP);
}
void GLBE_Init(void)
{
int i;
double t;
shaderstate.curentity = &r_worldentity;
be_maxpasses = gl_mtexarbable;
for (i = 0; i < FTABLE_SIZE; i++)
@ -910,12 +993,16 @@ void GLBE_Init(void)
}
shaderstate.shaderbits = ~0;
BE_SendPassBlendAndDepth(0);
BE_SendPassBlendDepthMask(0);
if (qglEnableClientState)
qglEnableClientState(GL_VERTEX_ARRAY);
currententity = &r_worldentity;
shaderstate.fogtexture = GenerateFogTexture();
}
//end tables
@ -954,11 +1041,36 @@ static void tcgen_environment(float *st, unsigned int numverts, float *xyz, floa
}
}
static float *tcgen(const shaderpass_t *pass, int cnt, float *dst, const mesh_t *mesh)
static void tcgen_fog(float *st, unsigned int numverts, float *xyz)
{
int i;
vec3_t viewer;
vec3_t rorg;
float z;
vec4_t zmat;
//generate a simple matrix to calc only the projected z coord
zmat[0] = -shaderstate.modelviewmatrix[2];
zmat[1] = -shaderstate.modelviewmatrix[6];
zmat[2] = -shaderstate.modelviewmatrix[10];
zmat[3] = -shaderstate.modelviewmatrix[14];
Vector4Scale(zmat, shaderstate.fogfar, zmat);
for (i = 0 ; i < numverts ; i++, xyz += sizeof(vecV_t)/sizeof(vec_t), st += 2 )
{
z = DotProduct(xyz, zmat) + zmat[3];
st[0] = z;
st[1] = realtime - (int)realtime;
}
}
static float *tcgen(unsigned int tcgen, int cnt, float *dst, const mesh_t *mesh)
{
int i;
vecV_t *src;
switch (pass->tcgen)
switch (tcgen)
{
default:
case TC_GEN_BASE:
@ -976,6 +1088,9 @@ static float *tcgen(const shaderpass_t *pass, int cnt, float *dst, const mesh_t
return (float*)mesh->st_array;
tcgen_environment(dst, cnt, (float*)mesh->xyz_array, (float*)mesh->normals_array);
return dst;
case TC_GEN_FOG:
tcgen_fog(dst, cnt, (float*)mesh->xyz_array);
return dst;
// case TC_GEN_DOTPRODUCT:
// return mesh->st_array[0];
@ -1078,6 +1193,25 @@ static void tcmod(const tcmod_t *tcmod, int cnt, const float *src, float *dst, c
}
}
static void GenerateTCFog(int passnum)
{
int m;
float *src;
mesh_t *mesh;
for (m = 0; m < shaderstate.meshcount; m++)
{
mesh = shaderstate.meshes[m];
src = tcgen(TC_GEN_FOG, mesh->numvertexes, texcoordarray[passnum]+mesh->vbofirstvert*2, mesh);
if (src != texcoordarray[passnum]+mesh->vbofirstvert*2)
{
//this shouldn't actually ever be true
memcpy(texcoordarray[passnum]+mesh->vbofirstvert*2, src, 8*mesh->numvertexes);
}
}
GL_SelectVBO(0);
qglTexCoordPointer(2, GL_FLOAT, 0, texcoordarray[passnum]);
}
static void GenerateTCMods(const shaderpass_t *pass, int passnum)
{
#if 1
@ -1088,7 +1222,7 @@ static void GenerateTCMods(const shaderpass_t *pass, int passnum)
{
mesh = shaderstate.meshes[m];
src = tcgen(pass, mesh->numvertexes, texcoordarray[passnum]+mesh->vbofirstvert*2, mesh);
src = tcgen(pass->tcgen, mesh->numvertexes, texcoordarray[passnum]+mesh->vbofirstvert*2, mesh);
//tcgen might return unmodified info
if (pass->numtcmods)
{
@ -1659,12 +1793,12 @@ static void GenerateColourMods(const shaderpass_t *pass)
mesh_t *meshlist;
meshlist = shaderstate.meshes[0];
if (meshlist->colors4b_array)
if (shaderstate.sourcevbo->colours4ub)
{
//hack...
GL_SelectVBO(0);
qglColorPointer(4, GL_UNSIGNED_BYTE, 0, meshlist->colors4b_array);
GL_SelectVBO(shaderstate.sourcevbo->vbocolours);
qglEnableClientState(GL_COLOR_ARRAY);
qglColorPointer(4, GL_UNSIGNED_BYTE, 0, shaderstate.sourcevbo->colours4ub);
qglShadeModel(GL_SMOOTH);
return;
}
@ -1743,6 +1877,7 @@ static void GenerateColourMods(const shaderpass_t *pass)
static void BE_GeneratePassTC(const shaderpass_t *pass, int passno)
{
pass += passno;
qglClientActiveTextureARB(mtexid0 + passno);
if (!pass->numtcmods)
{
//if there are no tcmods, pass through here as fast as possible
@ -1783,7 +1918,7 @@ static void BE_GeneratePassTC(const shaderpass_t *pass, int passno)
}
}
static void BE_SendPassBlendAndDepth(unsigned int sbits)
static void BE_SendPassBlendDepthMask(unsigned int sbits)
{
unsigned int delta;
@ -1917,6 +2052,15 @@ static void BE_SendPassBlendAndDepth(unsigned int sbits)
break;
}
}
if (delta & (SBITS_MASK_BITS))
{
qglColorMask(
(sbits&SBITS_MASK_RED)?GL_FALSE:GL_TRUE,
(sbits&SBITS_MASK_GREEN)?GL_FALSE:GL_TRUE,
(sbits&SBITS_MASK_BLUE)?GL_FALSE:GL_TRUE,
(sbits&SBITS_MASK_ALPHA)?GL_FALSE:GL_TRUE
);
}
}
static void BE_SubmitMeshChain(void)
@ -2011,6 +2155,7 @@ static void BE_SubmitMeshChain(void)
}
qglDrawRangeElements(GL_TRIANGLES, startv, endv, endi-starti, GL_INDEX_TYPE, shaderstate.sourcevbo->indicies + starti);
RQuantAdd(RQUANT_DRAWS, 1);
}
/*
if (qglUnlockArraysEXT)
@ -2037,7 +2182,7 @@ static void DrawPass(const shaderpass_t *pass)
if (i == lastpass)
return;
BE_SendPassBlendAndDepth(pass[i].shaderbits);
BE_SendPassBlendDepthMask(pass[i].shaderbits);
GenerateColourMods(pass+i);
tmu = 0;
for (; i < lastpass; i++)
@ -2048,17 +2193,10 @@ static void DrawPass(const shaderpass_t *pass)
continue;
if (pass[i].texgen == T_GEN_FULLBRIGHT && !TEXVALID(shaderstate.curtexnums->fullbright))
continue;
GL_MBind(tmu, Shader_TextureForPass(pass+i));
Shader_BindTextureForPass(tmu, pass+i, true);
BE_GeneratePassTC(pass, i);
if (tmu >= shaderstate.lastpasstmus)
{
qglEnable(GL_TEXTURE_2D);
qglEnableClientState(GL_TEXTURE_COORD_ARRAY);
}
switch (pass[i].blendmode)
{
case GL_DOT3_RGB_ARB:
@ -2088,9 +2226,7 @@ static void DrawPass(const shaderpass_t *pass)
for (i = tmu; i < shaderstate.lastpasstmus; i++)
{
GL_SelectTexture(i);
qglDisableClientState(GL_TEXTURE_COORD_ARRAY);
qglDisable(GL_TEXTURE_2D);
GL_LazyBind(i, 0, r_nulltex, false);
}
shaderstate.lastpasstmus = tmu;
GL_ApplyVertexPointer();
@ -2302,68 +2438,61 @@ static unsigned int BE_Program_Set_Attribute(const shaderprogparm_t *p, unsigned
static void BE_RenderMeshProgram(const shader_t *shader, const shaderpass_t *pass)
{
const shader_t *s = shader;
program_t *p = shader->prog;
int i;
unsigned int attr = 0;
int perm;
perm = 0;
if (TEXVALID(shaderstate.curtexnums->bump) && s->programhandle[perm|PERMUTATION_BUMPMAP].glsl)
if (TEXVALID(shaderstate.curtexnums->bump) && p->handle[perm|PERMUTATION_BUMPMAP].glsl)
perm |= PERMUTATION_BUMPMAP;
if (TEXVALID(shaderstate.curtexnums->specular) && s->programhandle[perm|PERMUTATION_SPECULAR].glsl)
if (TEXVALID(shaderstate.curtexnums->specular) && p->handle[perm|PERMUTATION_SPECULAR].glsl)
perm |= PERMUTATION_SPECULAR;
if (TEXVALID(shaderstate.curtexnums->fullbright) && s->programhandle[perm|PERMUTATION_FULLBRIGHT].glsl)
if (TEXVALID(shaderstate.curtexnums->fullbright) && p->handle[perm|PERMUTATION_FULLBRIGHT].glsl)
perm |= PERMUTATION_FULLBRIGHT;
if (TEXVALID(shaderstate.curtexnums->loweroverlay) && s->programhandle[perm|PERMUTATION_LOWER].glsl)
if (TEXVALID(shaderstate.curtexnums->loweroverlay) && p->handle[perm|PERMUTATION_LOWER].glsl)
perm |= PERMUTATION_LOWER;
if (TEXVALID(shaderstate.curtexnums->upperoverlay) && s->programhandle[perm|PERMUTATION_UPPER].glsl)
if (TEXVALID(shaderstate.curtexnums->upperoverlay) && p->handle[perm|PERMUTATION_UPPER].glsl)
perm |= PERMUTATION_UPPER;
if (r_glsl_offsetmapping.ival && TEXVALID(shaderstate.curtexnums->bump) && s->programhandle[perm|PERMUTATION_OFFSET].glsl)
if (r_glsl_offsetmapping.ival && TEXVALID(shaderstate.curtexnums->bump) && p->handle[perm|PERMUTATION_OFFSET].glsl)
perm |= PERMUTATION_OFFSET;
GL_SelectProgram(s->programhandle[perm].glsl);
GL_SelectProgram(p->handle[perm].glsl);
BE_SendPassBlendAndDepth(pass->shaderbits);
BE_SendPassBlendDepthMask(pass->shaderbits);
for (i = 0; i < s->numprogparams; i++)
for (i = 0; i < p->numparams; i++)
{
if (s->progparm[i].handle[perm] == -1)
if (p->parm[i].handle[perm] == -1)
continue; /*not in this permutation*/
attr |= BE_Program_Set_Attribute(&s->progparm[i], perm);
attr |= BE_Program_Set_Attribute(&p->parm[i], perm);
}
if (s->flags & SHADER_NOBUILTINATTR)
if (p->nofixedcompat)
{
qglDisableClientState(GL_COLOR_ARRAY);
qglDisableClientState(GL_VERTEX_ARRAY);
for (i = 0; i < pass->numMergedPasses; i++)
{
GL_MBind(i, Shader_TextureForPass(pass+i));
Shader_BindTextureForPass(i, pass+i, false);
}
for (i = 0; i < shaderstate.lastpasstmus; i++)
//we need this loop to fix up fixed-function stuff
for (; i < shaderstate.lastpasstmus; i++)
{
GL_SelectTexture(i);
qglDisableClientState(GL_TEXTURE_COORD_ARRAY);
qglDisable(GL_TEXTURE_2D);
GL_LazyBind(i, 0, r_nulltex, false);
}
shaderstate.lastpasstmus = 0;
shaderstate.lastpasstmus = pass->numMergedPasses;
}
else
{
GenerateColourMods(pass);
for (i = 0; i < pass->numMergedPasses; i++)
{
GL_MBind(i, Shader_TextureForPass(pass+i));
if (i >= shaderstate.lastpasstmus)
{
qglEnable(GL_TEXTURE_2D);
qglEnableClientState(GL_TEXTURE_COORD_ARRAY);
}
Shader_BindTextureForPass(i, pass+i, true);
BE_GeneratePassTC(pass, i);
}
for (; i < shaderstate.lastpasstmus; i++)
{
GL_SelectTexture(i);
qglDisableClientState(GL_TEXTURE_COORD_ARRAY);
qglDisable(GL_TEXTURE_2D);
GL_LazyBind(i, 0, r_nulltex, false);
}
shaderstate.lastpasstmus = pass->numMergedPasses;
GL_ApplyVertexPointer();
@ -2416,23 +2545,19 @@ void GLBE_SelectMode(backendmode_t mode, unsigned int flags)
#ifdef RTLIGHTS
if (mode == BEM_STENCIL)
{
qglColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
/*BEM_STENCIL doesn't support mesh writing*/
qglDisableClientState(GL_COLOR_ARRAY);
//disable all tmus
while(shaderstate.lastpasstmus>0)
{
GL_SelectTexture(--shaderstate.lastpasstmus);
qglDisable(GL_TEXTURE_2D);
qglDisableClientState(GL_TEXTURE_COORD_ARRAY);
GL_LazyBind(--shaderstate.lastpasstmus, 0, r_nulltex, false);
}
qglShadeModel(GL_FLAT);
//replace mode please
GL_TexEnv(GL_REPLACE);
//we don't write or blend anything (maybe alpha test... but mneh)
BE_SendPassBlendAndDepth(SBITS_MISC_DEPTHCLOSERONLY);
BE_SendPassBlendDepthMask(SBITS_MISC_DEPTHCLOSERONLY | SBITS_MASK_BITS);
//don't change cull stuff, and
//don't actually change stencil stuff - caller needs to be
@ -2441,27 +2566,20 @@ void GLBE_SelectMode(backendmode_t mode, unsigned int flags)
#endif
if (mode == BEM_DEPTHONLY)
{
qglColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
/*BEM_DEPTHONLY does support mesh writing, but its not the only way its used... FIXME!*/
qglDisableClientState(GL_COLOR_ARRAY);
while(shaderstate.lastpasstmus>0)
{
GL_SelectTexture(--shaderstate.lastpasstmus);
qglDisable(GL_TEXTURE_2D);
qglDisableClientState(GL_TEXTURE_COORD_ARRAY);
GL_LazyBind(--shaderstate.lastpasstmus, 0, r_nulltex, false);
}
qglShadeModel(GL_FLAT);
//we don't write or blend anything (maybe alpha test... but mneh)
BE_SendPassBlendAndDepth(SBITS_MISC_DEPTHWRITE);
BE_SendPassBlendDepthMask(SBITS_MISC_DEPTHWRITE | SBITS_MASK_BITS);
GL_TexEnv(GL_REPLACE);
GL_CullFace(SHADER_CULL_FRONT);
}
if (shaderstate.mode == BEM_STENCIL || shaderstate.mode == BEM_DEPTHONLY)
{
qglColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
}
#ifdef RTLIGHTS
if (mode == BEM_SMAPLIGHT)
{
@ -2487,6 +2605,21 @@ void GLBE_SelectMode(backendmode_t mode, unsigned int flags)
shaderstate.lightpassshader = R_RegisterCustom("lightpass", Shader_LightPass_Std, NULL);
}
}
if (mode == BEM_FOG)
{
while(shaderstate.lastpasstmus>0)
{
GL_LazyBind(--shaderstate.lastpasstmus, 0, r_nulltex, false);
}
GL_LazyBind(0, GL_TEXTURE_2D, shaderstate.fogtexture, true);
shaderstate.lastpasstmus = 1;
qglDisableClientState(GL_COLOR_ARRAY);
qglColor4f(1, 1, 1, 1);
qglShadeModel(GL_FLAT);
GL_TexEnv(GL_MODULATE);
BE_SendPassBlendDepthMask(SBITS_SRCBLEND_SRC_ALPHA | SBITS_DSTBLEND_ONE_MINUS_SRC_ALPHA | SBITS_MISC_DEPTHEQUALONLY);
}
#endif
}
shaderstate.mode = mode;
@ -2495,7 +2628,7 @@ void GLBE_SelectMode(backendmode_t mode, unsigned int flags)
void GLBE_SelectEntity(entity_t *ent)
{
if (shaderstate.curentity && shaderstate.curentity->flags & Q2RF_DEPTHHACK && qglDepthRange)
if (shaderstate.curentity->flags & Q2RF_DEPTHHACK && qglDepthRange)
qglDepthRange (gldepthmin, gldepthmax);
shaderstate.curentity = ent;
currententity = ent;
@ -2506,6 +2639,12 @@ void GLBE_SelectEntity(entity_t *ent)
qglDepthRange (gldepthmin, gldepthmin + 0.3*(gldepthmax-gldepthmin));
}
void BE_SelectFog(vec3_t colour, float alpha, float fardist)
{
qglColor4f(colour[0], colour[1], colour[2], alpha);
shaderstate.fogfar = 1/fardist;
}
#ifdef RTLIGHTS
void BE_SelectDLight(dlight_t *dl, vec3_t colour)
{
@ -2608,6 +2747,19 @@ static void DrawMeshes(void)
int passno;
passno = 0;
if (shaderstate.force2d)
{
RQuantAdd(RQUANT_2DBATCHES, 1);
}
else if (shaderstate.curentity == &r_worldentity)
{
RQuantAdd(RQUANT_WORLDBATCHES, 1);
}
else
{
RQuantAdd(RQUANT_ENTBATCHES, 1);
}
GL_SelectEBO(shaderstate.sourcevbo->vboe);
if (shaderstate.curshader->numdeforms)
GenerateVertexDeforms(shaderstate.curshader);
@ -2662,6 +2814,13 @@ static void DrawMeshes(void)
BE_SubmitMeshChain();
break;
case BEM_FOG:
GL_DeSelectProgram();
GenerateTCFog(0);
GL_ApplyVertexPointer();
BE_SubmitMeshChain();
break;
case BEM_DEPTHDARK:
if (shaderstate.curshader->flags & SHADER_HASLIGHTMAP)
{
@ -2670,12 +2829,10 @@ static void DrawMeshes(void)
qglDisableClientState(GL_COLOR_ARRAY);
while(shaderstate.lastpasstmus>0)
{
GL_SelectTexture(--shaderstate.lastpasstmus);
qglDisable(GL_TEXTURE_2D);
qglDisableClientState(GL_TEXTURE_COORD_ARRAY);
GL_LazyBind(--shaderstate.lastpasstmus, 0, r_nulltex, false);
}
GL_TexEnv(GL_REPLACE);
BE_SendPassBlendAndDepth(shaderstate.curshader->passes[0].shaderbits);
BE_SendPassBlendDepthMask(shaderstate.curshader->passes[0].shaderbits);
GL_ApplyVertexPointer();
BE_SubmitMeshChain();
@ -2684,7 +2841,7 @@ static void DrawMeshes(void)
//fallthrough
case BEM_STANDARD:
default:
if (shaderstate.curshader->programhandle[0].glsl)
if (shaderstate.curshader->prog)
{
BE_RenderMeshProgram(shaderstate.curshader, shaderstate.curshader->passes);
}
@ -2806,6 +2963,7 @@ void GLBE_SubmitBatch(batch_t *batch)
shaderstate.dummyvbo.svector = batch->mesh[0]->snormals_array;
shaderstate.dummyvbo.tvector = batch->mesh[0]->tnormals_array;
shaderstate.dummyvbo.colours4f = batch->mesh[0]->colors4f_array;
shaderstate.dummyvbo.colours4ub = batch->mesh[0]->colors4b_array;
shaderstate.sourcevbo = &shaderstate.dummyvbo;
lm = -1;
}
@ -2911,9 +3069,11 @@ static void BE_SubmitMeshesSortList(batch_t *sortlist)
if (batch->buildmeshes)
batch->buildmeshes(batch);
else
else if (batch->texture)
batch->shader = R_TextureAnimation(batch->ent->framestate.g[FS_REG].frame[0], batch->texture)->shader;
if (batch->shader->flags & SHADER_NODRAW)
continue;
if (batch->shader->flags & SHADER_NODLIGHT)
if (shaderstate.mode == BEM_LIGHT || shaderstate.mode == BEM_SMAPLIGHT)
continue;
@ -2921,7 +3081,8 @@ static void BE_SubmitMeshesSortList(batch_t *sortlist)
{
if (shaderstate.mode == BEM_STANDARD)
R_DrawSkyChain (batch);
continue;
if (shaderstate.mode != BEM_FOG)
continue;
}
BE_SubmitBatch(batch);
@ -2958,7 +3119,8 @@ static void BE_UpdateLightmaps(void)
glRect_t *theRect;
lightmap[lm]->modified = false;
theRect = &lightmap[lm]->rectchange;
GL_Bind(lightmap_textures[lm]);
checkglerror();
GL_MTBind(0, GL_TEXTURE_2D, lightmap_textures[lm]);
checkglerror();
switch (lightmap_bytes)
{
@ -2988,7 +3150,7 @@ static void BE_UpdateLightmaps(void)
{
lightmap[lm]->deluxmodified = false;
theRect = &lightmap[lm]->deluxrectchange;
GL_Bind(deluxmap_textures[lm]);
GL_MTBind(0, GL_TEXTURE_2D, deluxmap_textures[lm]);
qglTexSubImage2D(GL_TEXTURE_2D, 0, 0, theRect->t,
LMBLOCK_WIDTH, theRect->h, GL_RGB, GL_UNSIGNED_BYTE,
lightmap[lm]->deluxmaps+(theRect->t) *LMBLOCK_WIDTH*3);
@ -3000,6 +3162,7 @@ static void BE_UpdateLightmaps(void)
}
}
}
checkglerror();
}
batch_t *GLBE_GetTempBatch(void)
@ -3068,6 +3231,9 @@ void GLBE_DrawWorld (qbyte *vis)
extern cvar_t r_shadow_realtime_world, r_shadow_realtime_world_lightmaps;
batch_t *batches[SHADER_SORT_COUNT];
RSpeedLocals();
checkglerror();
GL_DoSwap();
if (!r_refdef.recurse)
@ -3091,7 +3257,7 @@ void GLBE_DrawWorld (qbyte *vis)
shaderstate.wbatch = 0;
}
BE_GenModelBatches(batches);
shaderstate.curentity = NULL;
shaderstate.curentity = &r_worldentity;
shaderstate.updatetime = cl.servertime;
#if 0
@ -3136,13 +3302,43 @@ void GLBE_DrawWorld (qbyte *vis)
BE_DrawPolys(false);
if (1)//gl_fog.value)
{
cvar_t *v;
vec3_t rgb;
float alpha;
float fardist;
v = Cvar_Get("_gl_fog", "0", 0, "experimental");
if (v->value)
{
v = Cvar_Get("_gl_fog_red", "1", 0, "experimental");
rgb[0] = v->value;
v = Cvar_Get("_gl_fog_green", "1", 0, "experimental");
rgb[1] = v->value;
v = Cvar_Get("_gl_fog_blue", "1", 0, "experimental");
rgb[2] = v->value;
v = Cvar_Get("_gl_fog_alpha", "1", 0, "experimental");
alpha = v->value;
v = Cvar_Get("_gl_fog_dist", "512", 0, "experimental");
fardist = v->value;
BE_SelectMode(BEM_FOG, 0);
BE_SelectFog(rgb, alpha, fardist);
GLBE_SubmitMeshes(true, batches);
}
}
BE_SelectEntity(&r_worldentity);
shaderstate.updatetime = realtime;
checkglerror();
}
void BE_DrawNonWorld (void)
{
batch_t *batches[SHADER_SORT_COUNT];
checkglerror();
if (shaderstate.wmesh > shaderstate.maxwmesh)
{
int newm = shaderstate.wmesh;
@ -3162,13 +3358,14 @@ void BE_DrawNonWorld (void)
shaderstate.wbatch = 0;
BE_GenModelBatches(batches);
shaderstate.curentity = NULL;
shaderstate.updatetime = cl.servertime;
GLBE_SubmitMeshes(false, batches);
BE_SelectEntity(&r_worldentity);
shaderstate.updatetime = realtime;
checkglerror();
}
#endif

View file

@ -193,7 +193,7 @@ void R_Bloom_InitTextures(void)
memset(data, 255, size);
if (!TEXVALID(bs.tx_screen))
bs.tx_screen = GL_AllocNewTexture(bs.scr_w, bs.scr_h);
GL_Bind(bs.tx_screen);
GL_MTBind(0, GL_TEXTURE_2D, bs.tx_screen);
qglTexImage2D (GL_TEXTURE_2D, 0, GL_RGB, bs.scr_w, bs.scr_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
@ -255,7 +255,7 @@ R_Bloom_DrawEffect
*/
void R_Bloom_DrawEffect(void)
{
GL_Bind(bs.tx_effect);
GL_MTBind(0, GL_TEXTURE_2D, bs.tx_effect);
qglEnable(GL_BLEND);
qglBlendFunc(GL_ONE, GL_ONE);
qglColor4f(r_bloom_alpha.value, r_bloom_alpha.value, r_bloom_alpha.value, 1.0f);
@ -386,7 +386,7 @@ void R_Bloom_GeneratexDiamonds(void)
qglLoadIdentity();
//copy small scene into bs.tx_effect
GL_Bind(bs.tx_effect);
GL_MTBind(0, GL_TEXTURE_2D, bs.tx_effect);
qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, bs.smp_w, bs.smp_h);
//start modifying the small scene corner
@ -459,13 +459,13 @@ void R_Bloom_DownsampleView( void )
int midsample_height = bs.size_downsample * bs.smp_t;
//copy the screen and draw resized
GL_Bind(bs.tx_screen);
GL_MTBind(0, GL_TEXTURE_2D, bs.tx_screen);
qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bs.vp_x, vid.pixelheight - (bs.vp_y + bs.vp_h), bs.vp_w, bs.vp_h);
R_Bloom_Quad(0, vid.pixelheight-midsample_height, midsample_width, midsample_height, bs.scr_s, bs.scr_t);
//now copy into Downsampling (mid-sized) texture
GL_Bind(bs.tx_downsample);
GL_MTBind(0, GL_TEXTURE_2D, bs.tx_downsample);
qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, midsample_width, midsample_height);
//now draw again in bloom size
@ -476,15 +476,14 @@ void R_Bloom_DownsampleView( void )
qglEnable(GL_BLEND);
qglBlendFunc(GL_ONE, GL_ONE);
qglColor4f(0.5f, 0.5f, 0.5f, 1.0f);
GL_Bind(bs.tx_screen);
GL_MTBind(0, GL_TEXTURE_2D, bs.tx_screen);
R_Bloom_Quad(0, vid.pixelheight-bs.smp_h, bs.smp_w, bs.smp_h, bs.scr_s, bs.scr_t);
qglColor4f(1.0f, 1.0f, 1.0f, 1.0f);
qglDisable(GL_BLEND);
}
else
{ //downsample simple
GL_Bind(bs.tx_screen);
GL_MTBind(0, GL_TEXTURE_2D, bs.tx_screen);
qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bs.vp_x, vid.pixelheight - (bs.vp_y + bs.vp_h), bs.vp_w, bs.vp_h);
R_Bloom_Quad(0, vid.pixelheight-bs.smp_h, bs.smp_w, bs.smp_h, bs.scr_s, bs.scr_t);
}
@ -551,7 +550,7 @@ void R_BloomBlend (void)
buh = bs.size_backup * bs.smp_t;
//copy the screen space we'll use to work into the backup texture
GL_Bind(bs.tx_backup);
GL_MTBind(0, GL_TEXTURE_2D, bs.tx_backup);
qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, buw, buh);
//create the bloom image
@ -562,7 +561,7 @@ void R_BloomBlend (void)
//restore the screen-backup to the screen
qglDisable(GL_BLEND);
GL_Bind(bs.tx_backup);
GL_MTBind(0, GL_TEXTURE_2D, bs.tx_backup);
qglColor4f(1, 1, 1, 1);
R_Bloom_Quad(0,
vid.pixelheight - (buh),

View file

@ -41,7 +41,7 @@ static void GL_Upload8Pal32 (qbyte *data, qbyte *pal, int width, int height, uns
void GL_UploadFmt(texid_t tex, char *name, enum uploadfmt fmt, void *data, void *palette, int width, int height, unsigned int flags)
{
GL_Bind(tex);
GL_MTBind(0, GL_TEXTURE_2D, tex);
switch(fmt)
{
case TF_INVALID:
@ -220,7 +220,7 @@ void GL_Texture_Anisotropic_Filtering_Callback (struct cvar_s *var, char *oldval
{
if (!(glt->flags & IF_NOMIPMAP))
{
GL_Bind (glt->texnum);
GL_MTBind(0, GL_TEXTURE_2D, glt->texnum);
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, anfactor);
}
}
@ -265,7 +265,7 @@ void GL_Texturemode_Callback (struct cvar_s *var, char *oldvalue)
{
if (!(glt->flags & IF_NOMIPMAP))
{
GL_Bind (glt->texnum);
GL_MTBind(0, GL_TEXTURE_2D, glt->texnum);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
}
@ -300,7 +300,7 @@ void GL_Texturemode2d_Callback (struct cvar_s *var, char *oldvalue)
{
if (glt->flags & IF_NOMIPMAP)
{
GL_Bind (glt->texnum);
GL_MTBind(0, GL_TEXTURE_2D, glt->texnum);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max_2d);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max_2d);
}
@ -575,28 +575,28 @@ void GLDraw_Crosshair(void)
}
else
{
sizex = (size*vid.pixelwidth) / (float)vid.width;
sizey = (size*vid.pixelheight) / (float)vid.height;
sizex = (size*vid.rotpixelwidth) / (float)vid.width;
sizey = (size*vid.rotpixelheight) / (float)vid.height;
chc = size * chc;
}
sizex = (int)sizex;
sizex = ((sizex)*(int)vid.width) / (float)vid.pixelwidth;
sizex = ((sizex)*(int)vid.width) / (float)vid.rotpixelwidth;
sizey = (int)sizey;
sizey = ((sizey)*(int)vid.height) / (float)vid.pixelheight;
sizey = ((sizey)*(int)vid.height) / (float)vid.rotpixelheight;
for (sc = 0; sc < cl.splitclients; sc++)
{
SCR_CrosshairPosition(sc, &x, &y);
//translate to pixel coord, for rounding
x = ((x-sizex-chc)*vid.pixelwidth) / (float)vid.width;
y = ((y-sizey-chc)*vid.pixelheight) / (float)vid.height;
x = ((x-sizex-chc)*vid.rotpixelwidth) / (float)vid.width;
y = ((y-sizey-chc)*vid.rotpixelheight) / (float)vid.height;
//translate to screen coords
sx = ((x)*(int)vid.width) / (float)vid.pixelwidth;
sy = ((y)*(int)vid.height) / (float)vid.pixelheight;
sx = ((x)*(int)vid.width) / (float)vid.rotpixelwidth;
sy = ((y)*(int)vid.height) / (float)vid.rotpixelheight;
R2D_Image(sx, sy, sizex*2, sizey*2, 0, 0, 1, 1, shader);
}
@ -619,7 +619,7 @@ void GLDraw_TransPicTranslate (int x, int y, int width, int height, qbyte *pic,
if (gl_config.gles)
return; // TODO: NOT FIXED YET
GL_Bind (translate_texture);
GL_MTBind(0, GL_TEXTURE_2D, translate_texture);
c = width * height;
@ -793,11 +793,36 @@ Setup as if the screen was 320*200
*/
void GL_Set2D (void)
{
GL_SetShaderState2D(true);
Matrix4_Orthographic(r_refdef.m_projection, 0, vid.width, vid.height, 0, -99999, 99999);
Matrix4_Identity(r_refdef.m_view);
r_refdef.time = realtime;
extern cvar_t gl_screenangle;
float rad, ang;
float tmp[16], tmp2[16];
float *Matrix4_NewRotation(float a, float x, float y, float z);
float *Matrix4_NewTranslation(float x, float y, float z);
float w = vid.width, h = vid.height;
GL_SetShaderState2D(true);
ang = (gl_screenangle.value>0?(gl_screenangle.value+45):(gl_screenangle.value-45))/90;
ang = (int)ang * 90;
if (ang)
{ /*more expensive maths*/
rad = (ang * M_PI) / 180;
w = fabs(cos(rad)) * (vid.width) + fabs(sin(rad)) * (vid.height);
h = fabs(sin(rad)) * (vid.width) + fabs(cos(rad)) * (vid.height);
Matrix4_Orthographic(r_refdef.m_projection, w/-2.0f, w/2.0f, h/2.0f, h/-2.0f, -99999, 99999);
Matrix4_Identity(tmp);
Matrix4_Multiply(Matrix4_NewTranslation((vid.width/-2.0f), (vid.height/-2.0f), 0), tmp, tmp2);
Matrix4_Multiply(Matrix4_NewRotation(-ang, 0, 0, 1), tmp2, r_refdef.m_view);
}
else
{
Matrix4_Orthographic(r_refdef.m_projection, 0, vid.width, vid.height, 0, -99999, 99999);
Matrix4_Identity(r_refdef.m_view);
}
r_refdef.time = realtime;
/*flush that gl state*/
qglViewport (0, 0, vid.pixelwidth, vid.pixelheight);
@ -1638,8 +1663,8 @@ done:
if (flags&IF_CLAMP)
{
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
}
@ -2259,8 +2284,9 @@ void GL_Upload8 (char *name, qbyte *data, int width, int height, unsigned int fl
}
#endif
#endif
checkglerror();
GL_Upload32 (name, trans, width, height, flags);
checkglerror();
}
void GL_Upload8FB (qbyte *data, int width, int height, unsigned flags)
@ -2425,11 +2451,11 @@ TRACE(("dbg: GL_LoadTexture: new %s\n", identifier));
glt->flags = flags;
Hash_Add(&gltexturetable, glt->identifier, glt, (bucket_t*)(glt+1));
GL_Bind(glt->texnum);
checkglerror();
GL_MTBind(0, GL_TEXTURE_2D, glt->texnum);
GL_Upload8 ("8bit", data, width, height, flags, transtype);
checkglerror();
return glt->texnum;
}
@ -2466,7 +2492,7 @@ texid_t GL_LoadTextureFB (char *identifier, int width, int height, qbyte *data,
Hash_Add(&gltexturetable, glt->identifier, glt, (bucket_t*)(glt+1));
GL_Bind(glt->texnum);
GL_MTBind(0, GL_TEXTURE_2D, glt->texnum);
GL_Upload8FB (data, width, height, flags);
@ -2499,7 +2525,7 @@ texid_t GL_LoadTexture8Pal24 (char *identifier, int width, int height, qbyte *da
Hash_Add(&gltexturetable, glt->identifier, glt, (bucket_t*)(glt+1));
GL_Bind(glt->texnum);
GL_MTBind(0, GL_TEXTURE_2D, glt->texnum);
GL_Upload8Pal24 (data, palette24, width, height, flags);
@ -2531,7 +2557,7 @@ texid_t GL_LoadTexture8Pal32 (char *identifier, int width, int height, qbyte *da
Hash_Add(&gltexturetable, glt->identifier, glt, (bucket_t*)(glt+1));
GL_Bind(glt->texnum);
GL_MTBind(0, GL_TEXTURE_2D, glt->texnum);
GL_Upload8Pal32 (data, palette32, width, height, flags);
@ -2565,7 +2591,7 @@ texid_t GL_LoadTexture32 (char *identifier, int width, int height, void *data, u
Hash_Add(&gltexturetable, glt->identifier, glt, (bucket_t*)(glt+1));
GL_Bind(glt->texnum);
GL_MTBind(0, GL_TEXTURE_2D, glt->texnum);
GL_Upload32 (identifier, data, width, height, flags);
@ -2599,7 +2625,7 @@ texid_t GL_LoadTexture32_BGRA (char *identifier, int width, int height, unsigned
Hash_Add(&gltexturetable, glt->identifier, glt, (bucket_t*)(glt+1));
GL_Bind(glt->texnum);
GL_MTBind(0, GL_TEXTURE_2D, glt->texnum);
GL_Upload32_BGRA (identifier, data, width, height, flags);
@ -2644,7 +2670,7 @@ texid_t GL_LoadCompressed(char *name)
Hash_Add(&gltexturetable, glt->identifier, glt, (bucket_t*)(glt+1));
GL_Bind(glt->texnum);
GL_MTBind(0, GL_TEXTURE_2D, glt->texnum);
if (!GL_UploadCompressed(file, &glt->width, &glt->height, (unsigned int *)&glt->flags))
return r_nulltex;
@ -2681,7 +2707,7 @@ texid_t GL_LoadTexture8Grey (char *identifier, int width, int height, unsigned c
Hash_Add(&gltexturetable, glt->identifier, glt, (bucket_t*)(glt+1));
GL_Bind(glt->texnum);
GL_MTBind(0, GL_TEXTURE_2D, glt->texnum);
GL_Upload8Grey (data, width, height, flags);
@ -2720,7 +2746,7 @@ texid_t GL_LoadTexture8Bump (char *identifier, int width, int height, unsigned c
Hash_Add(&gltexturetable, glt->identifier, glt, (bucket_t*)(glt+1));
GL_Bind(glt->texnum);
GL_MTBind(0, GL_TEXTURE_2D, glt->texnum);
GL_UploadBump (data, width, height, flags, bumpscale);

View file

@ -949,14 +949,14 @@ void Font_Free(struct font_s *f)
void Font_BeginString(struct font_s *font, int vx, int vy, int *px, int *py)
{
curfont = font;
*px = (vx*vid.pixelwidth) / (float)vid.width;
*py = (vy*vid.pixelheight) / (float)vid.height;
*px = (vx*vid.rotpixelwidth) / (float)vid.width;
*py = (vy*vid.rotpixelheight) / (float)vid.height;
}
void Font_BeginScaledString(struct font_s *font, float vx, float vy, float *px, float *py)
{
curfont = font;
*px = (vx*vid.pixelwidth) / (float)vid.width;
*py = (vy*vid.pixelheight) / (float)vid.height;
*px = (vx*vid.rotpixelwidth) / (float)vid.width;
*py = (vy*vid.rotpixelheight) / (float)vid.height;
}
void Font_EndString(struct font_s *font)
@ -1163,10 +1163,10 @@ int Font_DrawChar(int px, int py, unsigned int charcode)
if (c->texplane >= DEFAULTPLANE)
{
sx = ((px+c->left)*(int)vid.width) / (float)vid.pixelwidth;
sy = ((py+c->top)*(int)vid.height) / (float)vid.pixelheight;
sw = ((curfont->charheight)*vid.width) / (float)vid.pixelwidth;
sh = ((curfont->charheight)*vid.height) / (float)vid.pixelheight;
sx = ((px+c->left)*(int)vid.width) / (float)vid.rotpixelwidth;
sy = ((py+c->top)*(int)vid.height) / (float)vid.rotpixelheight;
sw = ((curfont->charheight)*vid.width) / (float)vid.rotpixelwidth;
sh = ((curfont->charheight)*vid.height) / (float)vid.rotpixelheight;
if (c->texplane == DEFAULTPLANE)
v = Font_BeginChar(fontplanes.defaultfont);
@ -1175,10 +1175,10 @@ int Font_DrawChar(int px, int py, unsigned int charcode)
}
else
{
sx = ((px+c->left)*(int)vid.width) / (float)vid.pixelwidth;
sy = ((py+c->top)*(int)vid.height) / (float)vid.pixelheight;
sw = ((c->bmw)*vid.width) / (float)vid.pixelwidth;
sh = ((c->bmh)*vid.height) / (float)vid.pixelheight;
sx = ((px+c->left)*(int)vid.width) / (float)vid.rotpixelwidth;
sy = ((py+c->top)*(int)vid.height) / (float)vid.rotpixelheight;
sw = ((c->bmw)*vid.width) / (float)vid.rotpixelwidth;
sh = ((c->bmh)*vid.height) / (float)vid.rotpixelheight;
v = Font_BeginChar(fontplanes.texnum[c->texplane]);
}
@ -1275,10 +1275,10 @@ float Font_DrawScaleChar(float px, float py, float cw, float ch, unsigned int ch
if (c->texplane >= DEFAULTPLANE)
{
sx = ((px+c->left));//*(int)vid.width) / (float)vid.pixelwidth;
sy = ((py+c->top));//*(int)vid.height) / (float)vid.pixelheight;
sw = ((curfont->charheight*cw));//*vid.width) / (float)vid.pixelwidth;
sh = ((curfont->charheight*ch));//*vid.height) / (float)vid.pixelheight;
sx = ((px+c->left));//*(int)vid.width) / (float)vid.rotpixelwidth;
sy = ((py+c->top));//*(int)vid.height) / (float)vid.rotpixelheight;
sw = ((curfont->charheight*cw));//*vid.width) / (float)vid.rotpixelwidth;
sh = ((curfont->charheight*ch));//*vid.height) / (float)vid.rotpixelheight;
if (c->texplane == DEFAULTPLANE)
v = Font_BeginChar(fontplanes.defaultfont);
@ -1287,10 +1287,10 @@ float Font_DrawScaleChar(float px, float py, float cw, float ch, unsigned int ch
}
else
{
sx = ((px+c->left));//*(int)vid.width) / (float)vid.pixelwidth;
sy = ((py+c->top));//*(int)vid.height) / (float)vid.pixelheight;
sw = ((c->bmw*cw));//*vid.width) / (float)vid.pixelwidth;
sh = ((c->bmh*ch));//*vid.height) / (float)vid.pixelheight;
sx = ((px+c->left));//*(int)vid.width) / (float)vid.rotpixelwidth;
sy = ((py+c->top));//*(int)vid.height) / (float)vid.rotpixelheight;
sw = ((c->bmw*cw));//*vid.width) / (float)vid.rotpixelwidth;
sh = ((c->bmh*ch));//*vid.height) / (float)vid.rotpixelheight;
v = Font_BeginChar(fontplanes.texnum[c->texplane]);
}

View file

@ -117,7 +117,7 @@ void GL_DrawHeightmapModel (entity_t *e)
else
#endif
{ //single texture
GL_Bind(hm->textures[x+y*SECTIONS]);
GL_MTBind(0, GL_TEXTURE_2D, hm->textures[x+y*SECTIONS]);
qglBegin(GL_QUADS);
subsize = hm->terrainsize/hm->numsegs;
minx = x*subsize;
@ -138,7 +138,7 @@ void GL_DrawHeightmapModel (entity_t *e)
}
qglEnd();
GL_Bind(hm->detailtexture);
GL_MTBind(0, GL_TEXTURE_2D, hm->detailtexture);
qglEnable(GL_BLEND);
qglBlendFunc (GL_ZERO, GL_SRC_COLOR);

View file

@ -686,7 +686,7 @@ void R_DrawHLModel(entity_t *curent)
{
tex_w = 1.0f / model.textures[skins[mesh->skinindex]].w;
tex_h = 1.0f / model.textures[skins[mesh->skinindex]].h;
GL_Bind(model.texnums[skins[mesh->skinindex]]);
GL_LazyBind(0, GL_TEXTURE_2D, model.texnums[skins[mesh->skinindex]], false);
}
GL_Draw_HL_AliasFrame((short *) ((qbyte *) model.header + mesh->index), transformed, tex_w, tex_h);

View file

@ -224,7 +224,7 @@ void RMod_Think (void)
GetProcessAffinityMask(me, &proc, &sys);
relightthreads = 0;
for (i = 0; i < sizeof(proc)*8; i++)
if (proc & (1u<<i))
if (proc & ((size_t)1u<<i))
relightthreads++;
/*subtract 1*/
if (relightthreads <= 1)
@ -716,9 +716,9 @@ model_t *RMod_LoadModel (model_t *mod, qboolean crash)
}
#endif
#ifdef MAP_PROC
if (!strcmp(com_token, "PROC")) //custom format, text based, specifies skeletal models to load and which md5anim files to use.
if (!strcmp(com_token, "CM")) //doom3 map.
{
if (!Mod_LoadMap_Proc (mod, buf))
if (!D3_LoadMap_CollisionMap (mod, (char*)buf))
continue;
break;
}

View file

@ -216,6 +216,7 @@ typedef struct vbo_s
int vboe;
index_t *indicies;
void *vertdata; /*internal use*/
int vbocoord;
vecV_t *coord;
@ -744,7 +745,7 @@ typedef struct {
//
typedef enum {mod_brush, mod_sprite, mod_alias, mod_dummy, mod_halflife, mod_heightmap} modtype_t;
typedef enum {fg_quake, fg_quake2, fg_quake3, fg_halflife, fg_new, fg_doom} fromgame_t; //useful when we have very similar model types. (eg quake/halflife bsps)
typedef enum {fg_quake, fg_quake2, fg_quake3, fg_halflife, fg_new, fg_doom, fg_doom3} fromgame_t; //useful when we have very similar model types. (eg quake/halflife bsps)
#define EF_ROCKET 1 // leave a trail
#define EF_GRENADE 2 // leave a trail
@ -781,6 +782,18 @@ typedef union {
} doom;
} specificmodeltype_t;
typedef struct
{
int walkno;
int area[2];
vec3_t plane;
float dist;
vec3_t min;
vec3_t max;
int numpoints;
vec4_t *points;
} portal_t;
typedef struct model_s
{
char name[MAX_QPATH];
@ -869,6 +882,8 @@ typedef struct model_s
unsigned checksum;
unsigned checksum2;
portal_t *portal;
unsigned int numportals;
modelfuncs_t funcs;
//

View file

@ -118,7 +118,7 @@ void GLR_NetGraph (void)
Draw_FunString(8, y, st);
y += 8;
GL_Bind(netgraphtexture);
GL_MTBind(0, GL_TEXTURE_2D, netgraphtexture);
qglTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA,
NET_TIMINGS, NET_GRAPHHEIGHT, 0, GL_RGBA,
@ -178,7 +178,7 @@ void GLR_FrameTimeGraph (int frametime)
Draw_FunString(8, y, st);
y += 8;
GL_Bind(netgraphtexture);
GL_MTBind(0, GL_TEXTURE_2D, netgraphtexture);
qglTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA,
NET_TIMINGS, NET_GRAPHHEIGHT, 0, GL_RGBA,

View file

@ -80,6 +80,8 @@ cvar_t gl_reporttjunctions = SCVAR("gl_reporttjunctions","0");
cvar_t gl_finish = SCVAR("gl_finish","0");
cvar_t gl_dither = SCVAR("gl_dither", "1");
extern cvar_t gl_screenangle;
cvar_t r_polygonoffset_submodel_factor = SCVAR("r_polygonoffset_submodel_factor", "0.05");
cvar_t r_polygonoffset_submodel_offset = SCVAR("r_polygonoffset_submodel_offset", "25");
@ -380,7 +382,7 @@ void GL_SetupSceneProcessingTextures (void)
}
}
GL_Bind(scenepp_texture_warp);
GL_MTBind(0, GL_TEXTURE_2D, scenepp_texture_warp);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, PP_WARP_TEX_SIZE, PP_WARP_TEX_SIZE, 0, GL_RGB, GL_UNSIGNED_BYTE, pp_warp_tex);
@ -424,7 +426,7 @@ void GL_SetupSceneProcessingTextures (void)
}
}
GL_Bind(scenepp_texture_edge);
GL_MTBind(0, GL_TEXTURE_2D, scenepp_texture_edge);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, PP_WARP_TEX_SIZE, PP_WARP_TEX_SIZE, 0, GL_RGB, GL_UNSIGNED_BYTE, pp_edge_tex);
@ -512,7 +514,11 @@ void R_RotateForEntity (float *modelview, const entity_t *e, const model_t *mod)
{
/*FIXME: no bob*/
float simpleview[16];
Matrix4_ModelViewMatrix(simpleview, vec3_origin, vec3_origin);
vec3_t ang, f, r, u;
ang[0] = 0;
ang[1] = 0;
ang[2] = gl_screenangle.value;
Matrix4_ModelViewMatrix(simpleview, ang, vec3_origin);
Matrix4_Multiply(simpleview, m, modelview);
}
else
@ -1001,6 +1007,7 @@ void R_SetupGL (void)
{
float screenaspect;
int x, x2, y2, y, w, h;
vec3_t newa;
float fov_x, fov_y;
@ -1077,7 +1084,11 @@ void R_SetupGL (void)
Matrix4_Orthographic(r_refdef.m_projection, 0, r_refdef.vrect.width, 0, r_refdef.vrect.height, -9999, 9999);
}
Matrix4_ModelViewMatrixFromAxis(r_refdef.m_view, vpn, vright, vup, r_refdef.vieworg);
VectorCopy(r_refdef.viewangles, newa);
newa[0] = r_refdef.viewangles[0];
newa[1] = r_refdef.viewangles[1];
newa[2] = r_refdef.viewangles[2] + gl_screenangle.value;
Matrix4_ModelViewMatrix(r_refdef.m_view, newa, r_refdef.vieworg);
}
if (qglLoadMatrixf)
@ -1499,7 +1510,7 @@ static void R_RenderMotionBlur(void)
PPL_RevertToKnownState();
GL_Bind(sceneblur_texture);
GL_LazyBind(0, GL_TEXTURE_2D, sceneblur_texture, false);
// go 2d
qglMatrixMode(GL_PROJECTION);
@ -1643,7 +1654,7 @@ qboolean R_RenderScene_Fish(void)
qglDisable(GL_TEXTURE_2D);
qglEnable(GL_TEXTURE_CUBE_MAP_ARB);
GL_BindType(GL_TEXTURE_CUBE_MAP_ARB, scenepp_fisheye_texture);
GL_MTBind(0, GL_TEXTURE_CUBE_MAP_ARB, scenepp_fisheye_texture);
for (i = 0; i < 6; i++)
qglCopyTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + i, 0, GL_RGB, 0, 0, cmapsize, cmapsize, 0);
qglTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
@ -1685,20 +1696,14 @@ qboolean R_RenderScene_Fish(void)
// render normal view
R_RenderScene ();
qglDisable(GL_TEXTURE_2D);
qglEnable(GL_TEXTURE_CUBE_MAP_ARB);
GL_BindType(GL_TEXTURE_CUBE_MAP_ARB, scenepp_fisheye_texture);
GL_MTBind(0, GL_TEXTURE_CUBE_MAP_ARB, scenepp_fisheye_texture);
qglCopyTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + order[i], 0, 0, 0, 0, vid.pixelheight - (prect.y + cmapsize), cmapsize, cmapsize);
qglEnable(GL_TEXTURE_2D);
qglDisable(GL_TEXTURE_CUBE_MAP_ARB);
}
//qglClear (GL_COLOR_BUFFER_BIT);
qglViewport (prect.x, vid.pixelheight - (prect.y+prect.height), prect.width, prect.height);
qglDisable(GL_TEXTURE_2D);
GL_BindType(GL_TEXTURE_CUBE_MAP_ARB, scenepp_fisheye_texture);
qglEnable(GL_TEXTURE_CUBE_MAP_ARB);
GL_LazyBind(0, GL_TEXTURE_CUBE_MAP_ARB, scenepp_fisheye_texture, false);
if (scenepp_panorama_program && ffov.value < 0)
{

View file

@ -455,11 +455,7 @@ void GLCrosshairimage_Callback(struct cvar_s *var, char *oldvalue);
void GLCrosshair_Callback(struct cvar_s *var, char *oldvalue);
void GLCrosshaircolor_Callback(struct cvar_s *var, char *oldvalue);
void GLR_Menutint_Callback (struct cvar_s *var, char *oldvalue);
void GLVID_Conwidth_Callback(struct cvar_s *var, char *oldvalue);
void GLVID_Conautoscale_Callback(struct cvar_s *var, char *oldvalue);
void GLVID_Conheight_Callback(struct cvar_s *var, char *oldvalue);
void GLV_Gamma_Callback(struct cvar_s *var, char *oldvalue);
void GL_Font_Callback(struct cvar_s *var, char *oldvalue);
void GLR_DeInit (void)
{
@ -977,6 +973,9 @@ TRACE(("dbg: GLR_NewMap: tp\n"));
TP_NewMap();
R_SetSky(cl.skyname);
if (cl.worldmodel->fromgame == fg_doom3)
D3_GenerateAreas(cl.worldmodel);
#ifdef RTLIGHTS
if (r_shadow_realtime_dlight.ival || r_shadow_realtime_world.ival)
{

View file

@ -53,10 +53,8 @@ void GLBE_ClearVBO(vbo_t *vbo)
if (j == 7)
qglDeleteBuffersARB(1, &vboh[i]);
}
if (!vbo->vbocoord)
BZ_Free(vbo->coord);
if (!vbo->vboe)
BZ_Free(vbo->indicies);
if (vbo->vertdata)
BZ_Free(vbo->vertdata);
BZ_Free(vbo->meshlist);
memset(vbo, 0, sizeof(*vbo));
}
@ -128,6 +126,16 @@ static qboolean GL_BuildVBO(vbo_t *vbo, void *vdata, int vsize, void *edata, int
return true;
}
void *allocbuf(char **p, int elements, int elementsize)
{
void *ret;
*p += elementsize - 1;
*p -= (unsigned int)*p & (elementsize-1);
ret = *p;
*p += elements*elementsize;
return ret;
}
void GLBE_GenBrushModelVBO(model_t *mod)
{
unsigned int maxvboverts;
@ -141,9 +149,8 @@ void GLBE_GenBrushModelVBO(model_t *mod)
unsigned int meshes;
vbo_t *vbo;
char *vboedata;
mesh_t *m;
char *vbovdata;
char *p;
if (!mod->numsurfaces)
return;
@ -189,17 +196,18 @@ void GLBE_GenBrushModelVBO(model_t *mod)
sizeof(vec3_t)+ //tdir
sizeof(vec4_t); //colours
vbovdata = BZ_Malloc(maxvboverts*pervertsize);
vboedata = BZ_Malloc(maxvboelements*sizeof(index_t));
vbo->vertdata = BZ_Malloc((maxvboverts+1)*pervertsize + (maxvboelements+1)*sizeof(index_t));
vbo->coord = (vecV_t*)(vbovdata);
vbo->texcoord = (vec2_t*)((char*)vbo->coord+maxvboverts*sizeof(*vbo->coord));
vbo->lmcoord = (vec2_t*)((char*)vbo->texcoord+maxvboverts*sizeof(*vbo->texcoord));
vbo->normals = (vec3_t*)((char*)vbo->lmcoord+maxvboverts*sizeof(*vbo->lmcoord));
vbo->svector = (vec3_t*)((char*)vbo->normals+maxvboverts*sizeof(*vbo->normals));
vbo->tvector = (vec3_t*)((char*)vbo->svector+maxvboverts*sizeof(*vbo->svector));
vbo->colours4f = (vec4_t*)((char*)vbo->tvector+maxvboverts*sizeof(*vbo->tvector));
vbo->indicies = (index_t*)vboedata;
p = vbo->vertdata;
vbo->coord = allocbuf(&p, maxvboverts, sizeof(*vbo->coord));
vbo->texcoord = allocbuf(&p, maxvboverts, sizeof(*vbo->texcoord));
vbo->lmcoord = allocbuf(&p, maxvboverts, sizeof(*vbo->lmcoord));
vbo->normals = allocbuf(&p, maxvboverts, sizeof(*vbo->normals));
vbo->svector = allocbuf(&p, maxvboverts, sizeof(*vbo->svector));
vbo->tvector = allocbuf(&p, maxvboverts, sizeof(*vbo->tvector));
vbo->colours4f = allocbuf(&p, maxvboverts, sizeof(*vbo->colours4f));
vbo->indicies = allocbuf(&p, maxvboelements, sizeof(index_t));
vbo->meshcount = meshes;
vbo->meshlist = BZ_Malloc(meshes*sizeof(*vbo->meshlist));
@ -265,10 +273,10 @@ void GLBE_GenBrushModelVBO(model_t *mod)
vcount += v;
}
if (GL_BuildVBO(vbo, vbovdata, vcount*pervertsize, vboedata, ecount*sizeof(index_t)))
if (GL_BuildVBO(vbo, vbo->coord, vcount*pervertsize, vbo->indicies, ecount*sizeof(index_t)))
{
BZ_Free(vbovdata);
BZ_Free(vboedata);
BZ_Free(vbo->vertdata);
vbo->vertdata = NULL;
}
}
/* for (i=0 ; i<mod->numsurfaces ; i++)
@ -295,7 +303,7 @@ void GLBE_UploadAllLightmaps(void)
if (!lightmap[i]->modified)
continue;
lightmap[i]->modified = false;
GL_Bind(lightmap_textures[i]);
GL_MTBind(0, GL_TEXTURE_2D, lightmap_textures[i]);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
switch (lightmap_bytes)
@ -323,7 +331,7 @@ void GLBE_UploadAllLightmaps(void)
lightmap[i]->deluxrectchange.t = LMBLOCK_HEIGHT;
lightmap[i]->deluxrectchange.w = 0;
lightmap[i]->deluxrectchange.h = 0;
GL_Bind(deluxmap_textures[i]);
GL_MTBind(0, GL_TEXTURE_2D, deluxmap_textures[i]);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
qglTexImage2D (GL_TEXTURE_2D, 0, 3

View file

@ -156,6 +156,8 @@ skipwhite:
}
data++;
c = *data;
if (c == ',' && len)
break;
} while (c>32);
if (len == MAX_TOKEN_CHARS)
@ -708,8 +710,9 @@ static void Shader_EntityMergable ( shader_t *shader, shaderpass_t *pass, char *
shader->flags |= SHADER_ENTITY_MERGABLE;
}
static void Shader_ProgAutoFields(program_t *prog);
/*program text is already loaded, this function parses the 'header' of it to see which permutations it provides, and how many times we need to recompile it*/
static void Shader_LoadPermutations(union programhandle_u *handle, char *script, int qrtype)
static void Shader_LoadPermutations(program_t *prog, char *script, int qrtype)
{
static char *permutationname[] =
{
@ -749,7 +752,7 @@ static void Shader_LoadPermutations(union programhandle_u *handle, char *script,
break;
};
memset(handle, 0, sizeof(*handle)*PERMUTATIONS);
memset(prog->handle, 0, sizeof(*prog->handle)*PERMUTATIONS);
for (p = 0; p < PERMUTATIONS; p++)
{
if (qrenderer != qrtype)
@ -769,16 +772,19 @@ static void Shader_LoadPermutations(union programhandle_u *handle, char *script,
permutationdefines[pn++] = permutationname[n];
}
permutationdefines[pn++] = NULL;
handle[p].glsl = GLSlang_CreateProgram(permutationdefines, script, script);
prog->handle[p].glsl = GLSlang_CreateProgram(permutationdefines, script, script);
}
#endif
}
Shader_ProgAutoFields(prog);
}
typedef struct sgeneric_s
{
struct sgeneric_s *next;
char name[MAX_QPATH];
union programhandle_u handle[PERMUTATIONS];
qboolean failed;
program_t prog;
} sgeneric_t;
static sgeneric_t *sgenerics;
struct sbuiltin_s
@ -1110,6 +1116,64 @@ struct sbuiltin_s
"varying mediump vec2 tc;\n"
"varying lowp vec3 light;\n"
"void main (void)\n"
"{\n"
" gl_FragColor = texture2D(s_t0, tc);\n"
"#ifdef UPPER\n"
" gl_FragColor.rgb += texture2D(s_t2, tc).rgb*e_uppercolour;\n"
"#endif\n"
"#ifdef LOWER\n"
" gl_FragColor.rgb += texture2D(s_t1, tc).rgb*e_lowercolour;\n"
"#endif\n"
" gl_FragColor.rgb *= light;\n"
"#ifdef FULLBRIGHT\n"
" gl_FragColor += texture2D(s_t3, tc);\n"
"#endif\n"
"}\n"
"#endif\n"
},
{QR_OPENGL, 110, "defaultskin",
"!!permu FULLBRIGHT\n"
"!!permu LOWER\n"
"!!permu UPPER\n"
//"#version 110\n"
"#ifdef VERTEX_SHADER\n"
"uniform mat4 m_modelview;\n"
"uniform mat4 m_projection;\n"
"attribute vec3 v_position;\n"
"attribute vec2 v_texcoord;\n"
"varying vec2 tc;\n"
"attribute vec3 v_normal;\n"
"uniform vec3 e_light_dir;\n"
"uniform vec3 e_light_mul;\n"
"uniform vec3 e_light_ambient;\n"
"varying vec3 light;\n"
"void main (void)\n"
"{\n"
" light = e_light_ambient + (dot(v_normal,e_light_dir)*e_light_mul);\n"
" tc = v_texcoord;\n"
" gl_Position = m_projection * m_modelview * vec4(v_position, 1.0);\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform sampler2D s_t0;\n" /*tex_diffuse*/
"#ifdef LOWER\n"
"uniform sampler2D s_t1;\n" /*tex_lower*/
"uniform vec3 e_lowercolour;\n"
"#endif\n"
"#ifdef UPPER\n"
"uniform sampler2D s_t2;\n" /*tex_upper*/
"uniform vec3 e_uppercolour;\n"
"#endif\n"
"#ifdef FULLBRIGHT\n"
"uniform sampler2D s_t3;\n" /*tex_fullbright*/
"#endif\n"
"varying vec2 tc;\n"
"varying vec3 light;\n"
"void main (void)\n"
"{\n"
" gl_FragColor = texture2D(s_t0, tc);\n"
@ -1140,7 +1204,7 @@ static void Shader_FlushGenerics(void)
free(g);
}
}
static void Shader_LoadGeneric(union programhandle_u *shader, char *name, int qrtype)
static program_t *Shader_LoadGeneric(char *name, int qrtype)
{
unsigned int i;
void *file;
@ -1150,27 +1214,34 @@ static void Shader_LoadGeneric(union programhandle_u *shader, char *name, int qr
{
if (!strcmp(name, g->name))
{
memcpy(shader, g->handle, sizeof(g->handle));
return;
if (g->failed)
return NULL;
g->prog.refs++;
return &g->prog;
}
}
if (strlen(name) >= sizeof(g->name))
return; /*name overflow*/
return NULL; /*name overflow*/
g = malloc(sizeof(*g));
memset(g, 0, sizeof(*g));
strcpy(g->name, name);
g->next = sgenerics;
sgenerics = g;
g->prog.refs = 1;
FS_LoadFile(name, &file);
if (file)
{
Shader_LoadPermutations(g->handle, file, qrtype);
Shader_LoadPermutations(&g->prog, file, qrtype);
FS_FreeFile(file);
g->prog.refs++;
return &g->prog;
}
else
{
memset(g->handle, 0, sizeof(g->handle));
for (i = 0; *sbuiltins[i].name; i++)
{
if (sbuiltins[i].qrtype == qrenderer && !strcmp(sbuiltins[i].name, name))
@ -1187,16 +1258,18 @@ static void Shader_LoadGeneric(union programhandle_u *shader, char *name, int qr
continue;
}
#endif
Shader_LoadPermutations(g->handle, sbuiltins[i].body, sbuiltins[i].qrtype);
break;
Shader_LoadPermutations(&g->prog, sbuiltins[i].body, sbuiltins[i].qrtype);
g->prog.refs++;
return &g->prog;
}
}
}
memcpy(shader, g->handle, sizeof(g->handle));
g->failed = true;
return NULL;
}
static void Shader_ProgAutoFields(shader_t *shader)
static void Shader_ProgAutoFields(program_t *prog)
{
unsigned int i, p;
qboolean found;
@ -1233,21 +1306,21 @@ static void Shader_ProgAutoFields(shader_t *shader)
{"e_light_ambient", SP_E_L_AMBIENT},
{NULL}
};
shader->numprogparams = 0;
prog->numparams = 0;
#ifdef GLQUAKE
if (qrenderer == QR_OPENGL)
{
if (gl_config.nofixedfunc)
shader->flags |= SHADER_NOBUILTINATTR;
prog->nofixedcompat = true;
for (p = 0; p < PERMUTATIONS; p++)
{
if (!shader->programhandle[p].glsl)
if (!prog->handle[p].glsl)
continue;
GLSlang_UseProgram(shader->programhandle[p].glsl);
GLSlang_UseProgram(prog->handle[p].glsl);
for (i = 0; i < 8; i++)
{
uniformloc = qglGetUniformLocationARB(shader->programhandle[p].glsl, va("s_t%i", i));
uniformloc = qglGetUniformLocationARB(prog->handle[p].glsl, va("s_t%i", i));
if (uniformloc != -1)
qglUniform1iARB(uniformloc, i);
}
@ -1257,24 +1330,24 @@ static void Shader_ProgAutoFields(shader_t *shader)
found = false;
for (p = 0; p < PERMUTATIONS; p++)
{
if (!shader->programhandle[p].glsl)
if (!prog->handle[p].glsl)
continue;
GLSlang_UseProgram(shader->programhandle[p].glsl);
GLSlang_UseProgram(prog->handle[p].glsl);
if (u[i].ptype >= SP_FIRSTUNIFORM)
uniformloc = qglGetUniformLocationARB(shader->programhandle[p].glsl, u[i].name);
uniformloc = qglGetUniformLocationARB(prog->handle[p].glsl, u[i].name);
else
uniformloc = qglGetAttribLocationARB(shader->programhandle[p].glsl, u[i].name);
uniformloc = qglGetAttribLocationARB(prog->handle[p].glsl, u[i].name);
if (uniformloc != -1)
found = true;
shader->progparm[shader->numprogparams].handle[p] = uniformloc;
prog->parm[prog->numparams].handle[p] = uniformloc;
}
if (found)
{
shader->progparm[shader->numprogparams].type = u[i].ptype;
shader->numprogparams++;
prog->parm[prog->numparams].type = u[i].ptype;
prog->numparams++;
if (u[i].ptype < SP_FIRSTUNIFORM)
shader->flags |= SHADER_NOBUILTINATTR;
prog->nofixedcompat = true;
}
}
GLSlang_UseProgram(0);
@ -1330,16 +1403,17 @@ static void Shader_SLProgramName (shader_t *shader, shaderpass_t *pass, char **p
programbody[end-start] = 0;
*ptr = end+1;/*skip over it all*/
Shader_LoadPermutations(shader->programhandle, programbody, qrtype);
Shader_ProgAutoFields(shader);
shader->prog = malloc(sizeof(*shader->prog));
memset(shader->prog, 0, sizeof(shader->prog));
shader->prog->refs = 1;
Shader_LoadPermutations(shader->prog, programbody, qrtype);
BZ_Free(programbody);
}
return;
}
Shader_LoadGeneric(shader->programhandle, Shader_ParseString(ptr), qrtype);
Shader_ProgAutoFields(shader);
shader->prog = Shader_LoadGeneric(Shader_ParseString(ptr), qrtype);
}
static void Shader_GLSLProgramName (shader_t *shader, shaderpass_t *pass, char **ptr)
@ -1444,26 +1518,30 @@ static void Shader_ProgramParam ( shader_t *shader, shaderpass_t *pass, char **p
int p;
qboolean foundone;
unsigned int uniformloc;
if (!shader->programhandle[0].glsl)
program_t *prog = shader->prog;
if (!prog)
{
Con_Printf("shader %s: param without program set\n", shader->name);
}
else if (shader->numprogparams == SHADER_PROGPARMS_MAX)
else if (prog->numparams == SHADER_PROGPARMS_MAX)
Con_Printf("shader %s: too many parms\n", shader->name);
else
{
if (prog->refs != 1)
Con_Printf("shader %s: parms on shared shader\n", shader->name);
foundone = false;
shader->progparm[shader->numprogparams].type = parmtype;
prog->parm[prog->numparams].type = parmtype;
for (p = 0; p < PERMUTATIONS; p++)
{
if (!shader->programhandle[p].glsl)
if (!prog->handle[p].glsl)
continue;
GLSlang_UseProgram(shader->programhandle[p].glsl);
GLSlang_UseProgram(prog->handle[p].glsl);
if (parmtype >= SP_FIRSTUNIFORM)
uniformloc = qglGetUniformLocationARB(shader->programhandle[p].glsl, token);
uniformloc = qglGetUniformLocationARB(prog->handle[p].glsl, token);
else
uniformloc = qglGetAttribLocationARB(shader->programhandle[p].glsl, token);
shader->progparm[shader->numprogparams].handle[p] = uniformloc;
uniformloc = qglGetAttribLocationARB(prog->handle[p].glsl, token);
prog->parm[prog->numparams].handle[p] = uniformloc;
if (uniformloc != -1)
{
foundone = true;
@ -1474,17 +1552,17 @@ static void Shader_ProgramParam ( shader_t *shader, shaderpass_t *pass, char **p
break;
case SP_TEXTURE:
case SP_CONSTI:
shader->progparm[shader->numprogparams].ival = specialint;
prog->parm[prog->numparams].ival = specialint;
break;
case SP_CONSTF:
shader->progparm[shader->numprogparams].fval = specialfloat;
prog->parm[prog->numparams].fval = specialfloat;
break;
case SP_CVARF:
case SP_CVARI:
shader->progparm[shader->numprogparams].pval = cv;
prog->parm[prog->numparams].pval = cv;
break;
case SP_CVAR3F:
shader->progparm[shader->numprogparams].pval = cv;
prog->parm[prog->numparams].pval = cv;
qglUniform3fvARB(uniformloc, 1, specialvec);
break;
default:
@ -1495,7 +1573,7 @@ static void Shader_ProgramParam ( shader_t *shader, shaderpass_t *pass, char **p
if (!foundone && !silent)
Con_Printf("shader %s: param \"%s\" not found\n", shader->name, token);
else
shader->numprogparams++;
prog->numparams++;
GLSlang_UseProgram(0);
}
@ -1503,6 +1581,18 @@ static void Shader_ProgramParam ( shader_t *shader, shaderpass_t *pass, char **p
#endif
}
static void Shader_DiffuseMap(shader_t *shader, shaderpass_t *pass, char **ptr)
{
char *token;
token = Shader_ParseString(ptr);
shader->defaulttextures.base = R_LoadHiResTexture(token, NULL, 0);
}
static void Shader_Translucent(shader_t *shader, shaderpass_t *pass, char **ptr)
{
shader->flags |= SHADER_BLEND;
}
static shaderkey_t shaderkeys[] =
{
{"cull", Shader_Cull},
@ -1522,6 +1612,17 @@ static shaderkey_t shaderkeys[] =
{"hlslprogram", Shader_HLSLProgramName}, //for d3d
{"param", Shader_ProgramParam},
/*doom3 compat*/
{"diffusemap", Shader_DiffuseMap},
{"bumpmap", NULL},
{"specularmap", NULL},
{"nonsolid", NULL},
{"noimpact", NULL},
{"translucent", Shader_Translucent},
{"noshadows", NULL},
{"nooverlays", NULL},
{"nofragment", NULL},
{NULL, NULL}
};
@ -1870,7 +1971,15 @@ static void Shaderpass_BlendFunc (shader_t *shader, shaderpass_t *pass, char **p
pass->shaderbits &= ~(SBITS_BLEND_BITS);
token = Shader_ParseString (ptr);
if ( !Q_stricmp (token, "blend"))
if ( !Q_stricmp (token, "diffusemap"))
{
//if the shader is translucent then this pass must be meant to be blended
if (shader->flags & SHADER_BLEND)
pass->shaderbits |= SBITS_SRCBLEND_SRC_ALPHA | SBITS_DSTBLEND_ONE_MINUS_SRC_ALPHA;
else
pass->shaderbits |= SBITS_SRCBLEND_NONE | SBITS_DSTBLEND_NONE;
}
else if ( !Q_stricmp (token, "blend"))
{
pass->shaderbits |= SBITS_SRCBLEND_SRC_ALPHA | SBITS_DSTBLEND_ONE_MINUS_SRC_ALPHA;
}
@ -1891,6 +2000,8 @@ static void Shaderpass_BlendFunc (shader_t *shader, shaderpass_t *pass, char **p
pass->shaderbits |= Shader_BlendFactor(token, false);
token = Shader_ParseString (ptr);
if (*token == ',')
token = Shader_ParseString (ptr);
pass->shaderbits |= Shader_BlendFactor(token, true);
}
}
@ -2010,28 +2121,31 @@ static void Shaderpass_Scale ( shader_t *shader, shaderpass_t *pass, char **ptr
tcmod = &pass->tcmods[pass->numtcmods];
token = Shader_ParseString ( ptr );
if (!strcmp(token, "static"))
{
tcmod->type = SHADER_TCMOD_SCALE;
tcmod->args[0] = Shader_ParseFloat ( ptr );
}
else
{
Con_Printf("Bad shader scale\n");
return;
}
tcmod->type = SHADER_TCMOD_SCALE;
token = Shader_ParseString ( ptr );
if (!strcmp(token, "static"))
{
tcmod->args[0] = Shader_ParseFloat ( ptr );
}
else
{
tcmod->args[0] = atof(token);
}
while (**ptr == ' ' || **ptr == '\t')
*ptr+=1;
if (**ptr == ',')
*ptr+=1;
token = Shader_ParseString ( ptr );
if (!strcmp(token, "static"))
{
tcmod->type = SHADER_TCMOD_SCALE;
tcmod->args[1] = Shader_ParseFloat ( ptr );
}
else
{
Con_Printf("Bad shader scale\n");
return;
tcmod->args[1] = atof(token);
}
pass->numtcmods++;
@ -2115,28 +2229,103 @@ static void Shaderpass_NoLightMap ( shader_t *shader, shaderpass_t *pass, char *
pass->rgbgen = RGB_GEN_IDENTITY;
}
static void Shaderpass_MaskColor(shader_t *shader, shaderpass_t *pass, char **ptr)
{
pass->shaderbits |= SBITS_MASK_RED|SBITS_MASK_GREEN|SBITS_MASK_BLUE;
}
static void Shaderpass_MaskRed(shader_t *shader, shaderpass_t *pass, char **ptr)
{
pass->shaderbits |= SBITS_MASK_RED;
}
static void Shaderpass_MaskGreen(shader_t *shader, shaderpass_t *pass, char **ptr)
{
pass->shaderbits |= SBITS_MASK_GREEN;
}
static void Shaderpass_MaskBlue(shader_t *shader, shaderpass_t *pass, char **ptr)
{
pass->shaderbits |= SBITS_MASK_BLUE;
}
static void Shaderpass_MaskAlpha(shader_t *shader, shaderpass_t *pass, char **ptr)
{
pass->shaderbits |= SBITS_MASK_ALPHA;
}
static void Shaderpass_AlphaTest(shader_t *shader, shaderpass_t *pass, char **ptr)
{
if (Shader_ParseFloat(ptr) == 0.5)
pass->shaderbits |= SBITS_ATEST_GE128;
else
Con_Printf("unsupported alphatest value\n");
}
static void Shaderpass_TexGen(shader_t *shader, shaderpass_t *pass, char **ptr)
{
char *token = Shader_ParseString(ptr);
if (!strcmp(token, "normal"))
pass->tcgen = TC_GEN_NORMAL;
else if (!strcmp(token, "skybox"))
pass->tcgen = TC_GEN_SKYBOX;
else if (!strcmp(token, "wobblesky"))
{
pass->tcgen = TC_GEN_WOBBLESKY;
token = Shader_ParseString(ptr);
token = Shader_ParseString(ptr);
token = Shader_ParseString(ptr);
}
else if (!strcmp(token, "reflect"))
pass->tcgen = TC_GEN_REFLECT;
else
{
Con_Printf("texgen token not understood\n");
}
}
static void Shaderpass_CubeMap(shader_t *shader, shaderpass_t *pass, char **ptr)
{
char *token = Shader_ParseString(ptr);
int flags = Shader_SetImageFlags(shader);
if (pass->tcgen == TC_GEN_BASE)
pass->tcgen = TC_GEN_SKYBOX;
pass->texgen = T_GEN_SKYBOX;
pass->anim_frames[0] = r_nulltex;//Shader_FindImage(token, flags);
if (!TEXVALID(pass->anim_frames[0]))
{
pass->texgen = T_GEN_SINGLEMAP;
pass->anim_frames[0] = missing_texture;
}
}
static shaderkey_t shaderpasskeys[] =
{
{"rgbgen", Shaderpass_RGBGen },
{"blendfunc", Shaderpass_BlendFunc },
{"depthfunc", Shaderpass_DepthFunc },
{"depthwrite", Shaderpass_DepthWrite },
{"alphafunc", Shaderpass_AlphaFunc },
{"tcmod", Shaderpass_TcMod },
{"map", Shaderpass_Map },
{"animmap", Shaderpass_AnimMap },
{"clampmap", Shaderpass_ClampMap },
{"videomap", Shaderpass_VideoMap },
{"tcgen", Shaderpass_TcGen },
{"envmap", Shaderpass_EnvMap },//for alienarena
{"nolightmap", Shaderpass_NoLightMap },//for alienarena
{"scale", Shaderpass_Scale },//for alienarena
{"scroll", Shaderpass_Scroll },//for alienarena
{"alphagen", Shaderpass_AlphaGen },
{"alphashift", Shaderpass_AlphaShift },//for alienarena
{"alphamask", Shaderpass_AlphaMask },//for alienarena
{"detail", Shaderpass_Detail },
{NULL, NULL }
{"rgbgen", Shaderpass_RGBGen},
{"blendfunc", Shaderpass_BlendFunc},
{"depthfunc", Shaderpass_DepthFunc},
{"depthwrite", Shaderpass_DepthWrite},
{"alphafunc", Shaderpass_AlphaFunc},
{"tcmod", Shaderpass_TcMod},
{"map", Shaderpass_Map},
{"animmap", Shaderpass_AnimMap},
{"clampmap", Shaderpass_ClampMap},
{"videomap", Shaderpass_VideoMap},
{"tcgen", Shaderpass_TcGen},
{"envmap", Shaderpass_EnvMap},//for alienarena
{"nolightmap", Shaderpass_NoLightMap},//for alienarena
{"scale", Shaderpass_Scale},//for alienarena
{"scroll", Shaderpass_Scroll},//for alienarena
{"alphagen", Shaderpass_AlphaGen},
{"alphashift", Shaderpass_AlphaShift},//for alienarena
{"alphamask", Shaderpass_AlphaMask},//for alienarena
{"detail", Shaderpass_Detail},
/*doom3 compat*/
{"blend", Shaderpass_BlendFunc},
{"maskcolor", Shaderpass_MaskColor},
{"maskred", Shaderpass_MaskRed},
{"maskgreen", Shaderpass_MaskGreen},
{"maskblue", Shaderpass_MaskBlue},
{"maskalpha", Shaderpass_MaskAlpha},
{"alphatest", Shaderpass_AlphaTest},
{"texgen", Shaderpass_TexGen},
{"cameracubemap",Shaderpass_CubeMap},
{NULL, NULL}
};
// ===============================================================
@ -2297,18 +2486,22 @@ void Shader_Free (shader_t *shader)
Hash_RemoveData(&shader_active_hash, shader->name, shader);
#ifdef GLQUAKE
if (qrenderer == QR_OPENGL)
if (qrenderer == QR_OPENGL && shader->prog)
{
program_t *prog = shader->prog;
int p;
for (p = 0; p < PERMUTATIONS; p++)
if (--prog->refs == 0)
{
if (shader->programhandle[p].glsl)
qglDeleteProgramObject_(shader->programhandle[p].glsl);
for (p = 0; p < PERMUTATIONS; p++)
{
if (prog->handle[p].glsl)
qglDeleteProgramObject_(prog->handle[p].glsl);
}
free(prog);
}
shader->prog = NULL;
}
#endif
memset(&shader->programhandle, 0, sizeof(shader->programhandle));
if (shader->skydome)
{
Z_Free (shader->skydome);
@ -2568,6 +2761,9 @@ void Shader_SetPassFlush (shaderpass_t *pass, shaderpass_t *pass2)
if ((pass->shaderbits & SBITS_ATEST_BITS) && (!(pass2->shaderbits & SBITS_MISC_DEPTHEQUALONLY) || pass2->texgen != T_GEN_LIGHTMAP))
return;
if ((pass->shaderbits & SBITS_MASK_BITS) != (pass2->shaderbits & SBITS_MASK_BITS))
return;
// check if we can use multiple passes
if (pass2->blendmode == GL_DOT3_RGB_ARB)
{
@ -2714,18 +2910,24 @@ void Shader_Finish (shader_t *s)
pass = &s->passes[s->numpasses++];
pass = &s->passes[0];
pass->tcgen = TC_GEN_BASE;
pass->anim_frames[0] = R_LoadHiResTexture(s->name, NULL, IF_NOALPHA);
if (!TEXVALID(pass->anim_frames[0]))
if (TEXVALID(s->defaulttextures.base))
pass->texgen = T_GEN_DIFFUSE;
else
{
Con_Printf("Shader %s failed to load default texture\n", s->name);
pass->anim_frames[0] = missing_texture;
pass->texgen = T_GEN_SINGLEMAP;
pass->anim_frames[0] = R_LoadHiResTexture(s->name, NULL, IF_NOALPHA);
if (!TEXVALID(pass->anim_frames[0]))
{
Con_Printf("Shader %s failed to load default texture\n", s->name);
pass->anim_frames[0] = missing_texture;
}
Con_Printf("Shader %s with no passes and no surfaceparm nodraw, inserting pass\n", s->name);
}
pass->shaderbits |= SBITS_MISC_DEPTHWRITE;
pass->rgbgen = RGB_GEN_VERTEX;
pass->alphagen = ALPHA_GEN_IDENTITY;
pass->numMergedPasses = 1;
Shader_SetBlendmode(pass);
Con_Printf("Shader %s with no passes and no surfaceparm nodraw, inserting pass\n", s->name);
}
if (!Q_stricmp (s->name, "flareShader"))
@ -2749,7 +2951,7 @@ void Shader_Finish (shader_t *s)
s->sort = SHADER_SORT_DECAL;
}
if (r_vertexlight.value && !s->programhandle[0].glsl)
if (r_vertexlight.value && !s->prog)
{
// do we have a lightmap pass?
pass = s->passes;
@ -2836,7 +3038,7 @@ done:;
pass = s->passes;
for (i = 0; i < s->numpasses; i++, pass++)
{
if (!(pass->shaderbits & SBITS_BLEND_BITS))
if (!(pass->shaderbits & (SBITS_BLEND_BITS|SBITS_MASK_BITS)))
{
break;
}
@ -2933,7 +3135,7 @@ done:;
s->flags &= ~SHADER_DEPTHWRITE;
}
if (s->programhandle[0].glsl)
if (s->prog)
{
if (!s->numpasses)
s->numpasses = 1;
@ -3293,23 +3495,14 @@ void Shader_DefaultBSPQ1(char *shortname, shader_t *s, const void *args)
"{\n"
"sort blend\n" /*make sure it always has the same sort order, so switching on/off wateralpha doesn't break stuff*/
"program defaultwarp\n"
"if r_wateralpha != 1\n"
"[\n"
"param cvarf r_wateralpha wateralpha\n"
"{\n"
"map $diffuse\n"
"tcmod turb 0 0 3 0.1\n"
"{\n"
"map $diffuse\n"
"tcmod turb 0 0 3 0.1\n"
"if r_wateralpha != 1\n"
"[\n"
"blendfunc gl_src_alpha gl_one_minus_src_alpha\n"
"}\n"
"]\n"
"if r_wateralpha == 1\n"
"[\n"
"param constf 1 wateralpha\n"
"{\n"
"map $diffuse\n"
"tcmod turb 0 0 3 0.1\n"
"}\n"
"]\n"
"]\n"
"}\n"
"surfaceparm nodlight\n"
"}\n"
);
@ -3808,9 +4001,16 @@ static int R_LoadShader ( char *name, shader_gen_t *defaultgen, const char *gena
if (defaultgen)
{
memset ( s, 0, sizeof( shader_t ) );
defaultgen(shortname, s, genargs);
Com_sprintf ( s->name, MAX_QPATH, shortname );
memset(s, 0, sizeof(shader_t));
Com_sprintf(s->name, MAX_QPATH, shortname);
if (!strcmp(shortname, "textures/common/clip"))
Shader_DefaultScript(shortname, s,
"{\n"
"surfaceparm nodraw\n"
"surfaceparm nodlight\n"
"}\n");
else
defaultgen(shortname, s, genargs);
Hash_Add(&shader_active_hash, s->name, s, &s->bucket);
s->generator = defaultgen;
s->genargs = genargs;
@ -3833,6 +4033,7 @@ void Shader_DoReload(void)
{
Con_Printf ( "Initializing Shaders.\n" );
COM_EnumerateFiles("materials/*.mtr", Shader_InitCallback, NULL);
COM_EnumerateFiles("shaders/*.shader", Shader_InitCallback, NULL);
COM_EnumerateFiles("scripts/*.shader", Shader_InitCallback, NULL);
//COM_EnumerateFiles("scripts/*.rscript", Shader_InitCallback, NULL);

View file

@ -1178,7 +1178,6 @@ static qboolean Sh_ScissorForBox(vec3_t mins, vec3_t maxs)
Matrix4_Project(v, v2, r_refdef.viewangles, r_refdef.vieworg, r_refdef.fov_x, r_refdef.fov_y);
v2[0]*=r_view_width;
v2[1]*=r_view_height;
// GL_TransformToScreen(v, v2);
//Con_Printf("%.3f %.3f %.3f %.3f transformed to %.3f %.3f %.3f %.3f\n", v[0], v[1], v[2], v[3], v2[0], v2[1], v2[2], v2[3]);
x = v2[0];
y = v2[1];
@ -1195,7 +1194,7 @@ static qboolean Sh_ScissorForBox(vec3_t mins, vec3_t maxs)
y1 = y2 = y;
}
}
#if 0
#if 1
// this code doesn't handle boxes with any points behind view properly
x1 = 1000;x2 = -1000;
y1 = 1000;y2 = -1000;
@ -1205,7 +1204,7 @@ static qboolean Sh_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;
GL_TransformToScreen(v, v2);
Matrix4_Project(v, v2, r_refdef.viewangles, r_refdef.vieworg, r_refdef.fov_x, r_refdef.fov_y);
v2[0]*=r_view_width;
v2[1]*=r_view_height;
//Con_Printf("%.3f %.3f %.3f %.3f transformed to %.3f %.3f %.3f %.3f\n", v[0], v[1], v[2], v[3], v2[0], v2[1], v2[2], v2[3]);
@ -1266,7 +1265,7 @@ void GL_EndRenderBuffer_DepthOnly(texid_t depthtexture, int texsize)
}
else
{
GL_Bind(depthtexture);
GL_MTBind(0, GL_TEXTURE_2D, depthtexture);
qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, texsize, texsize);
}
}
@ -1386,7 +1385,7 @@ void Sh_GenShadowMap (dlight_t *l, qbyte *lvis)
{
l->stexture = GL_AllocNewTexture(smsize, smsize);
GL_Bind(l->stexture);
GL_MTBind(0, GL_TEXTURE_2D, l->stexture);
qglTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32_ARB, smsize, smsize, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
// qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, smsize, smsize, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
@ -1537,7 +1536,8 @@ static void Sh_DrawShadowMapLight(dlight_t *l, vec3_t colour, qbyte *vvis)
bench.numlights++;
qglMatrixMode(GL_TEXTURE);
GL_MBind(7, l->stexture);
GL_MTBind(7, GL_TEXTURE_2D, l->stexture);
// qglEnable(GL_TEXTURE_2D);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
@ -1642,7 +1642,6 @@ static void Sh_DrawBrushModelShadow(dlight_t *dl, entity_t *e)
GL_SelectVBO(0);
GL_SelectEBO(0);
qglEnableClientState(GL_VERTEX_ARRAY);
qglEnable(GL_VERTEX_ARRAY);
BE_PushOffsetShadow(true);
@ -1741,7 +1740,6 @@ static void Sh_DrawStencilLightShadows(dlight_t *dl, qbyte *lvis, qbyte *vvis, q
GL_SelectVBO(0);
GL_SelectEBO(0);
qglEnableClientState(GL_VERTEX_ARRAY);
qglEnable(GL_VERTEX_ARRAY);
//draw cached world shadow mesh
qglVertexPointer(3, GL_FLOAT, sizeof(vecV_t), sm->verts);
qglDrawRangeElements(GL_TRIANGLES, 0, sm->numverts, sm->numindicies, GL_INDEX_TYPE, sm->indicies);

View file

@ -636,7 +636,7 @@ static void GL_DrawSkyGrid (texture_t *tex)
float time = cl.gametime+realtime-cl.gametimemark;
PPL_RevertToKnownState();
GL_Bind (tex->shader->defaulttextures.base);
GL_LazyBind(0, GL_TEXTURE_2D, tex->shader->defaulttextures.base, false);
speedscale = time*8;
speedscale -= (int)speedscale & ~127;
@ -649,7 +649,7 @@ static void GL_DrawSkyGrid (texture_t *tex)
}
qglEnable (GL_BLEND);
GL_Bind (tex->shader->defaulttextures.fullbright);
GL_LazyBind(0, GL_TEXTURE_2D, tex->shader->defaulttextures.fullbright, false);
speedscale = time*16;
speedscale -= (int)speedscale & ~127;

View file

@ -243,11 +243,10 @@ qboolean R_CullSphere (vec3_t origin, float radius);
#ifdef GLQUAKE
void R_TranslatePlayerSkin (int playernum);
void GL_Bind (texid_t texnum);
void GL_MBind(int tmunum, texid_t texnum);
void GL_MTBind(int tmu, int target, texid_t texnum); /*use this if you're going to change the texture object*/
void GL_LazyBind(int tmu, int target, texid_t texnum, qboolean arrays); /*use this if you don't care about the object itself, only that it is bound*/
void GL_CullFace(unsigned int sflags);
void GL_TexEnv(GLenum mode);
void GL_BindType (int type, texid_t texnum);
void GL_FlushBackEnd (void);
// Multitexture
@ -355,6 +354,9 @@ qboolean GL_LoadHeightmapModel (model_t *mod, void *buffer);
#ifdef MAP_DOOM
void GLR_DoomWorld();
#endif
qboolean D3_LoadMap_CollisionMap(model_t *mod, char *buf);
unsigned char *D3_CalcVis(model_t *mod, vec3_t org);
void D3_GenerateAreas(model_t *mod);
//gl_bloom.c
#ifdef GLQUAKE

View file

@ -122,12 +122,15 @@ enum
SBITS_MISC_DEPTHWRITE = 0x00001000,
SBITS_MISC_NODEPTHTEST = 0x00002000,
SBITS_MISC_DEPTHEQUALONLY = 0x00004000,
SBITS_MISC_DEPTHCLOSERONLY = 0x00008000,
// SBITS_MISC_POLYFILL_LINES = 0x00008000,
#define SBITS_MISC_BITS 0x0000f000
SBITS_MASK_RED = 0x00010000,
SBITS_MASK_GREEN = 0x00020000,
SBITS_MASK_BLUE = 0x00040000,
SBITS_MASK_ALPHA = 0x00080000,
#define SBITS_MASK_BITS 0x000f0000
};
@ -176,11 +179,15 @@ typedef struct shaderpass_s {
TC_GEN_ENVIRONMENT,
TC_GEN_DOTPRODUCT,
TC_GEN_VECTOR,
TC_GEN_FOG,
//these are really for use only in glsl stuff.
//these are really for use only in glsl stuff or perhaps cubemaps, as they generate 3d coords.
TC_GEN_NORMAL,
TC_GEN_SVECTOR,
TC_GEN_TVECTOR,
TC_GEN_SKYBOX,
TC_GEN_WOBBLESKY,
TC_GEN_REFLECT,
} tcgen;
int numtcmods;
tcmod_t tcmods[SHADER_MAX_TC_MODS];
@ -207,6 +214,7 @@ typedef struct shaderpass_s {
T_GEN_CURRENTRENDER,//copy the current screen to a texture, and draw that
T_GEN_VIDEOMAP, //use the media playback as an image source, updating each frame for which it is visible
T_GEN_SKYBOX, //use a skybox instead, otherwise T_GEN_SINGLEMAP
} texgen;
enum {
@ -300,6 +308,16 @@ union programhandle_u
{
int glsl;
};
typedef struct programshared_s
{
int refs;
qboolean nofixedcompat;
union programhandle_u handle[PERMUTATIONS];
int numparams;
shaderprogparm_t parm[SHADER_PROGPARMS_MAX];
} program_t;
typedef struct {
float factor;
float unit;
@ -344,12 +362,9 @@ struct shader_s
SHADER_NODLIGHT = 1 << 15, //from surfaceflags
SHADER_HASLIGHTMAP = 1 << 16,
SHADER_HASTOPBOTTOM = 1 << 17,
SHADER_NOBUILTINATTR = 1 << 18 /*using custom glsl attributes so don't feed it builtins*/
} flags;
union programhandle_u programhandle[PERMUTATIONS];
int numprogparams;
shaderprogparm_t progparm[SHADER_PROGPARMS_MAX];
program_t *prog;
shaderpass_t passes[SHADER_PASS_MAX];

View file

@ -1164,6 +1164,7 @@ char *ED_ParseEdict (progfuncs_t *progfuncs, char *data, edictrun_t *ent)
pbool init;
char keyname[256];
int n;
int nest = 1;
// eval_t *val;
@ -1179,12 +1180,20 @@ char *ED_ParseEdict (progfuncs_t *progfuncs, char *data, edictrun_t *ent)
// parse key
data = QCC_COM_Parse (data);
if (qcc_token[0] == '}')
{
if (--nest)
continue;
break;
}
if (qcc_token[0] == '{' && !qcc_token[1])
nest++;
if (!data)
{
printf ("ED_ParseEntity: EOF without closing brace\n");
return NULL;
}
if (nest > 1)
continue;
strncpy (keyname, qcc_token, sizeof(keyname)-1);
keyname[sizeof(keyname)-1] = 0;
@ -1714,6 +1723,11 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags)
file = QCC_COM_Parse(file);
if (file == NULL)
break; //finished reading file
else if (!strcmp(qcc_token, "Version"))
{
file = QCC_COM_Parse(file);
//qcc_token is a version number
}
else if (!strcmp(qcc_token, "entity"))
{
if (entsize == 0 && resethunk) //edicts have not yet been initialized, and this is a compleate load (memsize has been set)

View file

@ -536,8 +536,12 @@ void SV_Map_f (void)
snprintf (expanded, sizeof(expanded), "maps/%s.bsp", level);
if (!COM_FCheckExists (expanded))
{
Con_TPrintf (STL_CANTFINDMAP, expanded);
return;
snprintf (expanded, sizeof(expanded), "maps/%s.cm", level);
if (!COM_FCheckExists (expanded))
{
Con_TPrintf (STL_CANTFINDMAP, expanded);
return;
}
}
}
}

View file

@ -846,6 +846,9 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
{
strcpy (sv.name, server);
sprintf (sv.modelname,"maps/%s.bsp", server);
if (!COM_FCheckExists(sv.modelname))
if (COM_FCheckExists(va("maps/%s.cm", server)))
sprintf (sv.modelname,"maps/%s.cm", server);
}
sv.state = ss_loading;
sv.world.worldmodel = Mod_ForName (sv.modelname, true);