Try to make sense of hl2 materials.
This commit is contained in:
parent
6658565956
commit
586a92ec47
|
@ -355,7 +355,7 @@ void GL_DeselectVAO(void);
|
||||||
|
|
||||||
typedef struct texture_s
|
typedef struct texture_s
|
||||||
{
|
{
|
||||||
char name[64];
|
char name[128];
|
||||||
unsigned vwidth, vheight; //used for lightmap coord generation
|
unsigned vwidth, vheight; //used for lightmap coord generation
|
||||||
|
|
||||||
struct shader_s *shader;
|
struct shader_s *shader;
|
||||||
|
|
|
@ -627,7 +627,10 @@ qboolean Shader_ParseSkySides (char *shadername, char *texturename, texid_t *ima
|
||||||
"%s_%s",
|
"%s_%s",
|
||||||
"%s%s",
|
"%s%s",
|
||||||
"env/%s%s",
|
"env/%s%s",
|
||||||
"gfx/env/%s%s"
|
"gfx/env/%s%s",
|
||||||
|
#ifdef HL2BSPS
|
||||||
|
"materials/skybox/%s%s",
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
if (*texturename == '$')
|
if (*texturename == '$')
|
||||||
|
@ -663,7 +666,8 @@ qboolean Shader_ParseSkySides (char *shadername, char *texturename, texid_t *ima
|
||||||
}
|
}
|
||||||
if (!images[i]->width)
|
if (!images[i]->width)
|
||||||
{
|
{
|
||||||
Con_Printf("Sky \"%s\" missing texture: %s\n", shadername, path);
|
if (allokay)
|
||||||
|
Con_Printf("Sky \"%s\" missing texture: [gfx/env/]%s%s\n", shadername, texturename, skyname_suffix[countof(skyname_suffix)-1][i]);
|
||||||
images[i] = missing_texture;
|
images[i] = missing_texture;
|
||||||
allokay = false;
|
allokay = false;
|
||||||
}
|
}
|
||||||
|
@ -7069,8 +7073,12 @@ void Shader_DefaultSkinShell(parsestate_t *ps, const char *shortname, const void
|
||||||
void Shader_Default2D(parsestate_t *ps, const char *shortname, const void *genargs)
|
void Shader_Default2D(parsestate_t *ps, const char *shortname, const void *genargs)
|
||||||
{
|
{
|
||||||
shader_t *s = ps->s;
|
shader_t *s = ps->s;
|
||||||
|
qboolean wrap;
|
||||||
if (Shader_ParseShader(ps, "default2d"))
|
if (Shader_ParseShader(ps, "default2d"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
wrap = Com_FloatArgument(s->name, "WRAP", 4, 0);
|
||||||
|
|
||||||
if (sh_config.progs_supported && qrenderer != QR_DIRECT3D9
|
if (sh_config.progs_supported && qrenderer != QR_DIRECT3D9
|
||||||
#ifdef HAVE_LEGACY
|
#ifdef HAVE_LEGACY
|
||||||
&& !dpcompat_nopremulpics.ival
|
&& !dpcompat_nopremulpics.ival
|
||||||
|
@ -7080,35 +7088,35 @@ void Shader_Default2D(parsestate_t *ps, const char *shortname, const void *genar
|
||||||
//hexen2 needs premultiplied alpha to avoid looking ugly
|
//hexen2 needs premultiplied alpha to avoid looking ugly
|
||||||
//but that results in problems where things are drawn with alpha not 0, so scale vertex colour by alpha in the fragment program
|
//but that results in problems where things are drawn with alpha not 0, so scale vertex colour by alpha in the fragment program
|
||||||
Shader_DefaultScript(ps, shortname,
|
Shader_DefaultScript(ps, shortname,
|
||||||
"{\n"
|
va("{\n"
|
||||||
"affine\n"
|
"affine\n"
|
||||||
"nomipmaps\n"
|
"nomipmaps\n"
|
||||||
"program default2d#PREMUL\n"
|
"program default2d#PREMUL\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
"clampmap $diffuse\n"
|
"%s $diffuse\n"
|
||||||
"blendfunc gl_one gl_one_minus_src_alpha\n"
|
"blendfunc gl_one gl_one_minus_src_alpha\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
"sort additive\n"
|
"sort additive\n"
|
||||||
"}\n"
|
"}\n", (wrap?"map":"clampmap")
|
||||||
);
|
));
|
||||||
TEXASSIGN(s->defaulttextures->base, R_LoadHiResTexture(s->name, genargs, IF_PREMULTIPLYALPHA|IF_UIPIC|IF_NOPICMIP|IF_NOMIPMAP|IF_CLAMP|IF_HIGHPRIORITY));
|
TEXASSIGN(s->defaulttextures->base, R_LoadHiResTexture(s->name, genargs, IF_PREMULTIPLYALPHA|IF_UIPIC|IF_NOPICMIP|IF_NOMIPMAP|(wrap?0:IF_CLAMP)|IF_HIGHPRIORITY));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Shader_DefaultScript(ps, shortname,
|
Shader_DefaultScript(ps, shortname,
|
||||||
"{\n"
|
va("{\n"
|
||||||
"affine\n"
|
"affine\n"
|
||||||
"nomipmaps\n"
|
"nomipmaps\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
"clampmap $diffuse\n"
|
"%s $diffuse\n"
|
||||||
"rgbgen vertex\n"
|
"rgbgen vertex\n"
|
||||||
"alphagen vertex\n"
|
"alphagen vertex\n"
|
||||||
"blendfunc gl_src_alpha gl_one_minus_src_alpha\n"
|
"blendfunc gl_src_alpha gl_one_minus_src_alpha\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
"sort additive\n"
|
"sort additive\n"
|
||||||
"}\n"
|
"}\n", (wrap?"map":"clampmap")
|
||||||
);
|
));
|
||||||
TEXASSIGN(s->defaulttextures->base, R_LoadHiResTexture(s->name, genargs, IF_UIPIC|IF_NOPICMIP|IF_NOMIPMAP|IF_CLAMP|IF_HIGHPRIORITY));
|
TEXASSIGN(s->defaulttextures->base, R_LoadHiResTexture(s->name, genargs, IF_UIPIC|IF_NOPICMIP|IF_NOMIPMAP|(wrap?0:IF_CLAMP)|IF_HIGHPRIORITY));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void Shader_PolygonShader(struct shaderparsestate_s *ps, const char *shortname, const void *args)
|
void Shader_PolygonShader(struct shaderparsestate_s *ps, const char *shortname, const void *args)
|
||||||
|
@ -7276,6 +7284,305 @@ static void Shader_ReadShader(parsestate_t *ps, const char *shadersource, shader
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MATERIAL_VMT
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char type[MAX_QPATH];
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
char name[MAX_QPATH];
|
||||||
|
} tex[5];
|
||||||
|
char envmap[MAX_QPATH];
|
||||||
|
float alphatestref;
|
||||||
|
qboolean alphatest;
|
||||||
|
qboolean culldisable;
|
||||||
|
qboolean ignorez;
|
||||||
|
char *replaceblock;
|
||||||
|
} vmtstate_t;
|
||||||
|
|
||||||
|
static qboolean R_ReadVMT(const char *materialname, vmtstate_t *st);
|
||||||
|
static char *R_ParseVMTBlock(const char *fname, vmtstate_t *st, char *line)
|
||||||
|
{ //assumes the open { was already parsed, but will parse the close.
|
||||||
|
char *replace = NULL;
|
||||||
|
com_tokentype_t ttype;
|
||||||
|
char key[MAX_OSPATH];
|
||||||
|
char value[MAX_OSPATH];
|
||||||
|
char *qmark;
|
||||||
|
qboolean cond;
|
||||||
|
for(;line;)
|
||||||
|
{
|
||||||
|
line = COM_ParseType(line, key, sizeof(key), &ttype);
|
||||||
|
if (ttype == TTP_RAWTOKEN && !strcmp(key, "}"))
|
||||||
|
break; //end-of-block
|
||||||
|
line = COM_ParseType(line, value, sizeof(value), &ttype);
|
||||||
|
if (ttype == TTP_RAWTOKEN && !strcmp(value, "{"))
|
||||||
|
{ //sub block. we don't go into details here.
|
||||||
|
if (!Q_strcasecmp(key, "replace"))
|
||||||
|
replace = line;
|
||||||
|
else
|
||||||
|
Con_DPrintf("%s: Unknown block \"%s\"\n", fname, key);
|
||||||
|
line = R_ParseVMTBlock(fname, NULL, line);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((qmark = strchr(key, '?')))
|
||||||
|
{
|
||||||
|
*qmark++ = 0;
|
||||||
|
if (!Q_strcasecmp(key, "srgb"))
|
||||||
|
cond = !!(vid.flags & VID_SRGBAWARE);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Con_DPrintf("%s: Unknown vmt conditional \"%s\"\n", fname, key);
|
||||||
|
cond = false;
|
||||||
|
}
|
||||||
|
if (!cond)
|
||||||
|
{
|
||||||
|
*key = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
memmove(key, qmark, strlen(qmark)+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!*key || !st)
|
||||||
|
;
|
||||||
|
else if (!Q_strcasecmp(key, "include"))
|
||||||
|
{
|
||||||
|
if (!R_ReadVMT(value, st))
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else if (!Q_strcasecmp(key, "$basetexture") || !Q_strcasecmp(key, "$hdrbasetexture")) //fixme: hdr version should probably override the other. order matters.
|
||||||
|
Q_strncpyz(st->tex[0].name, value, sizeof(st->tex[0].name));
|
||||||
|
else if (!Q_strcasecmp(key, "$hdrcompressedtexture")) //named texture is R8G8B8E8 and needs to be decompressed manually... should probably just use e5bgr9 but we don't have a way to transcode it here.
|
||||||
|
;
|
||||||
|
else if (!Q_strcasecmp(key, "$basetexturetransform"))
|
||||||
|
;
|
||||||
|
else if (!Q_strcasecmp(key, "$bumpmap"))
|
||||||
|
;
|
||||||
|
else if (!Q_strcasecmp(key, "$ssbump"))
|
||||||
|
;
|
||||||
|
else if (!Q_strcasecmp(key, "$ssbumpmathfix"))
|
||||||
|
;
|
||||||
|
else if (!Q_strcasecmp(key, "$basetexture2") || !strcmp(key, "$texture2"))
|
||||||
|
Q_strncpyz(st->tex[1].name, value, sizeof(st->tex[1].name));
|
||||||
|
else if (!Q_strcasecmp(key, "$basetexturetransform2"))
|
||||||
|
;
|
||||||
|
else if (!Q_strcasecmp(key, "$surfaceprop"))
|
||||||
|
;
|
||||||
|
|
||||||
|
else if (!Q_strcasecmp(key, "$ignorez"))
|
||||||
|
st->ignorez = !!atoi(value);
|
||||||
|
else if (!Q_strcasecmp(key, "$nocull") && (!strcmp(value, "1")||!strcmp(value, "0")))
|
||||||
|
st->culldisable = atoi(value);
|
||||||
|
else if (!Q_strcasecmp(key, "$alphatest") && (!strcmp(value, "1")||!strcmp(value, "0")))
|
||||||
|
st->alphatest = atoi(value);
|
||||||
|
else if (!Q_strcasecmp(key, "$alphatestreference"))
|
||||||
|
st->alphatestref = atof(value);
|
||||||
|
else if (!Q_strcasecmp(key, "$alphafunc"))
|
||||||
|
{
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
}
|
||||||
|
else if (!Q_strcasecmp(key, "$alpha"))
|
||||||
|
{
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
}
|
||||||
|
else if (!Q_strcasecmp(key, "$translucent"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$additive"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$color"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$vertexcolor"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$vertexalpha"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$decal"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$decalscale"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$decalsize"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$envmap"))
|
||||||
|
Q_strncpyz(st->envmap, value, sizeof(st->envmap));
|
||||||
|
else if (!Q_strcasecmp(key, "$envmaptint"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$envmapmask"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$envmapcontrast"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$envmaptint"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$envmapsaturation"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$basealphaenvmapmask"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$normalmapalphaenvmapmask"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$crackmaterial"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$selfillum"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$selfillummask"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$selfillumtint"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$nofog"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$nomip"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$nodecal"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$detail"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$detailscale"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$detailtint"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$detailblendfactor"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$detailblendmode"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
|
||||||
|
else if (!Q_strcasecmp(key, "$surfaceprop2"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$AllowAlphaToCoverage"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$blendmodulatetexture"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
|
||||||
|
//water/reflection stuff
|
||||||
|
else if (!Q_strcasecmp(key, "$refracttexture"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$refractamount"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$refracttint"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$reflecttexture"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$reflectamount"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$reflecttint"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$fresnelpower"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$minreflectivity"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$maxreflectivity"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$normalmap"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$bumpframe"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$fogenable"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$fogcolor"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$fogstart"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$fogend"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$abovewater"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$underwateroverlay"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$reflectentities"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$scale"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$bottommaterial"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$scroll1"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
else if (!Q_strcasecmp(key, "$scroll2"))
|
||||||
|
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
|
||||||
|
|
||||||
|
else if (*key == '%')
|
||||||
|
; //editor lines
|
||||||
|
else
|
||||||
|
Con_Printf("%s: Unknown field \"%s\"\n", fname, key);
|
||||||
|
}
|
||||||
|
if (replace)
|
||||||
|
R_ParseVMTBlock(fname, st, replace);
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
static void Shader_GenerateFromVMT(parsestate_t *ps, vmtstate_t *st, const char *shortname)
|
||||||
|
{
|
||||||
|
size_t offset = 0;
|
||||||
|
char script[8192];
|
||||||
|
if (!*st->tex[0].name)
|
||||||
|
Q_strncpyz(st->tex[0].name, shortname, sizeof(st->tex[0].name));
|
||||||
|
|
||||||
|
//Q_strlcatfz(script, &offset, sizeof(script), "{\n");
|
||||||
|
if (!Q_strcasecmp(st->type, "WorldVertexTransition"))
|
||||||
|
{ //attempt to do terrain blending
|
||||||
|
Q_strncpyz(st->type, "defaultwall#TWOWAY", sizeof(st->type));
|
||||||
|
Q_strlcatfz(script, &offset, sizeof(script), "program \"%s\"\n", st->type);
|
||||||
|
Q_strlcatfz(script, &offset, sizeof(script), "diffusemap \"%s%s.vtf\"\n", strcmp(st->tex[0].name, "materials/")?"materials/":"", st->tex[0].name);
|
||||||
|
Q_strlcatfz(script, &offset, sizeof(script), "uppermap \"%s%s.vtf\"\n", strcmp(st->tex[1].name, "materials/")?"materials/":"", st->tex[1].name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Q_strncpyz(st->type, "defaultwall", sizeof(st->type)); //FIXME
|
||||||
|
|
||||||
|
Q_strlcatfz(script, &offset, sizeof(script), "program \"%s\"\n", st->type);
|
||||||
|
Q_strlcatfz(script, &offset, sizeof(script), "diffusemap \"%s%s.vtf\"\n", strcmp(st->tex[0].name, "materials/")?"materials/":"", st->tex[0].name);
|
||||||
|
}
|
||||||
|
if (*st->envmap)
|
||||||
|
Q_strlcatfz(script, &offset, sizeof(script), "reflectcube \"%s%s.vtf\"\n", strcmp(st->envmap, "materials/")?"materials/":"", st->envmap);
|
||||||
|
if (st->alphatest)
|
||||||
|
Q_strlcatfz(script, &offset, sizeof(script), "alphatest ge128\n");
|
||||||
|
if (st->culldisable)
|
||||||
|
Q_strlcatfz(script, &offset, sizeof(script), "cull disable\n");
|
||||||
|
if (st->ignorez)
|
||||||
|
Q_strlcatfz(script, &offset, sizeof(script), "nodepth\n");
|
||||||
|
Q_strlcatfz(script, &offset, sizeof(script), "}\n");
|
||||||
|
|
||||||
|
Shader_Reset(ps->s);
|
||||||
|
Shader_ReadShader(ps, script, NULL);
|
||||||
|
}
|
||||||
|
static qboolean R_ReadVMT(const char *fname, vmtstate_t *st)
|
||||||
|
{
|
||||||
|
char *line, *file = NULL;
|
||||||
|
com_tokentype_t ttype;
|
||||||
|
char token[MAX_QPATH];
|
||||||
|
char *prefix="", *postfix="";
|
||||||
|
|
||||||
|
//don't dupe the mandatory materials/ prefix
|
||||||
|
if (strncmp(fname, "materials/", 10))
|
||||||
|
prefix = "materials/";
|
||||||
|
if (strcmp(COM_GetFileExtension(fname, NULL), ".vmt"))
|
||||||
|
postfix = ".vmt";
|
||||||
|
Q_snprintfz(token, sizeof(token), "%s%s%s", prefix, fname, postfix);
|
||||||
|
|
||||||
|
file = FS_LoadMallocFile(token, NULL);
|
||||||
|
if (file)
|
||||||
|
{
|
||||||
|
line = file;
|
||||||
|
line = COM_ParseType(line, st->type, sizeof(st->type), &ttype);
|
||||||
|
line = COM_ParseType(line, token, sizeof(token), &ttype);
|
||||||
|
if (!strcmp(token, "{"))
|
||||||
|
{
|
||||||
|
line = R_ParseVMTBlock(fname, st, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BZ_Free(file);
|
||||||
|
return !!line;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
static qboolean Shader_ReadVMT(parsestate_t *ps, const char *filename)
|
||||||
|
{
|
||||||
|
vmtstate_t st;
|
||||||
|
memset(&st, 0, sizeof(st));
|
||||||
|
if (!R_ReadVMT(filename, &st))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Shader_GenerateFromVMT(ps, &st, filename);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static qboolean Shader_ParseShader(parsestate_t *ps, const char *parsename)
|
static qboolean Shader_ParseShader(parsestate_t *ps, const char *parsename)
|
||||||
{
|
{
|
||||||
size_t offset = 0, length;
|
size_t offset = 0, length;
|
||||||
|
@ -7293,6 +7600,11 @@ static qboolean Shader_ParseShader(parsestate_t *ps, const char *parsename)
|
||||||
char shaderfile[MAX_QPATH];
|
char shaderfile[MAX_QPATH];
|
||||||
if (!*token)
|
if (!*token)
|
||||||
{
|
{
|
||||||
|
#ifdef MATERIAL_VMT
|
||||||
|
if (Shader_ReadVMT(ps, parsename))
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
|
||||||
Q_snprintfz(shaderfile, sizeof(shaderfile), "%s.mat", parsename);
|
Q_snprintfz(shaderfile, sizeof(shaderfile), "%s.mat", parsename);
|
||||||
file = COM_LoadTempMoreFile(shaderfile, &length);
|
file = COM_LoadTempMoreFile(shaderfile, &length);
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,9 @@ cvar_t r_skyboxname = CVARFC ("r_skybox", "", CVAR_RENDERERCALLBACK | CVAR
|
||||||
cvar_t r_skybox_orientation = CVARFD ("r_glsl_skybox_orientation", "0 0 0 0", CVAR_SHADERSYSTEM, "Defines the axis around which skyboxes will rotate (the first three values). The fourth value defines the speed the skybox rotates at, in degrees per second.");
|
cvar_t r_skybox_orientation = CVARFD ("r_glsl_skybox_orientation", "0 0 0 0", CVAR_SHADERSYSTEM, "Defines the axis around which skyboxes will rotate (the first three values). The fourth value defines the speed the skybox rotates at, in degrees per second.");
|
||||||
cvar_t r_skyfog = CVARD ("r_skyfog", "0.5", "This controls an alpha-blend value for fog on skyboxes, cumulative with regular fog alpha.");
|
cvar_t r_skyfog = CVARD ("r_skyfog", "0.5", "This controls an alpha-blend value for fog on skyboxes, cumulative with regular fog alpha.");
|
||||||
|
|
||||||
|
#ifdef MATERIAL_VMT
|
||||||
|
static shader_t *forcedskyfaces[6];
|
||||||
|
#endif
|
||||||
static shader_t *forcedsky;
|
static shader_t *forcedsky;
|
||||||
static shader_t *skyboxface;
|
static shader_t *skyboxface;
|
||||||
static shader_t *skygridface;
|
static shader_t *skygridface;
|
||||||
|
@ -55,6 +58,9 @@ void R_SkyShutdown(void)
|
||||||
skyboxface = NULL;
|
skyboxface = NULL;
|
||||||
skygridface = NULL;
|
skygridface = NULL;
|
||||||
forcedsky = NULL;
|
forcedsky = NULL;
|
||||||
|
#ifdef MATERIAL_VMT
|
||||||
|
memset(forcedskyfaces, 0, sizeof(forcedskyfaces));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//lets the backend know which fallback envmap it can use.
|
//lets the backend know which fallback envmap it can use.
|
||||||
|
@ -89,8 +95,21 @@ void R_SetSky(const char *sky)
|
||||||
if (!*sky)
|
if (!*sky)
|
||||||
return; //no need to do anything
|
return; //no need to do anything
|
||||||
|
|
||||||
|
#ifdef MATERIAL_VMT //hl2 skies have specific shaders (with their own maps) for each face. can't automatically use cubemap optimisations - we would need to interrogate the shaders. :(
|
||||||
|
for (i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
static const char *facenames[] = {"rt", "bk", "lf", "ft", "up", "dn"};
|
||||||
|
forcedskyfaces[i] = R_RegisterCustom(va("materials/skybox/%s%s", sky, facenames[i]), SUF_NONE, NULL, NULL); //don't allow a fallback, so we know when it fails.
|
||||||
|
if (!forcedskyfaces[i])
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i == 6)
|
||||||
|
return; //okay, we have all 6 faces okay...
|
||||||
|
memset(forcedskyfaces, 0, sizeof(forcedskyfaces));
|
||||||
|
#endif
|
||||||
memset(&tex, 0, sizeof(tex));
|
memset(&tex, 0, sizeof(tex));
|
||||||
|
|
||||||
|
//equirectangular skies
|
||||||
tex.base = R_LoadHiResTexture(sky, "env:gfx/env", IF_LOADNOW|IF_NOMIPMAP);
|
tex.base = R_LoadHiResTexture(sky, "env:gfx/env", IF_LOADNOW|IF_NOMIPMAP);
|
||||||
if (tex.reflectcube && tex.reflectcube->status == TEX_LOADING)
|
if (tex.reflectcube && tex.reflectcube->status == TEX_LOADING)
|
||||||
COM_WorkerPartialSync(tex.reflectcube, &tex.reflectcube->status, TEX_LOADING);
|
COM_WorkerPartialSync(tex.reflectcube, &tex.reflectcube->status, TEX_LOADING);
|
||||||
|
@ -442,6 +461,13 @@ qboolean R_DrawSkyChain (batch_t *batch)
|
||||||
if (!opaque)
|
if (!opaque)
|
||||||
GL_DrawSkySphere(batch, skyshader);
|
GL_DrawSkySphere(batch, skyshader);
|
||||||
}
|
}
|
||||||
|
#ifdef MATERIAL_VMT
|
||||||
|
else if (forcedskyfaces[0])
|
||||||
|
{
|
||||||
|
R_CalcSkyChainBounds(batch);
|
||||||
|
GL_DrawSkyBox (NULL, batch);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
else if (skyboxtex && TEXVALID(*skyboxtex))
|
else if (skyboxtex && TEXVALID(*skyboxtex))
|
||||||
{ //draw a skybox if we were given the textures
|
{ //draw a skybox if we were given the textures
|
||||||
R_CalcSkyChainBounds(batch);
|
R_CalcSkyChainBounds(batch);
|
||||||
|
@ -1130,7 +1156,7 @@ static void GL_DrawSkyBox (texid_t *texnums, batch_t *s)
|
||||||
skyfacemesh.numindexes = 6;
|
skyfacemesh.numindexes = 6;
|
||||||
skyfacemesh.numvertexes = 4;
|
skyfacemesh.numvertexes = 4;
|
||||||
|
|
||||||
if (!skyboxface)
|
if (texnums && !skyboxface)
|
||||||
skyboxface = R_RegisterShader("skyboxface", SUF_NONE,
|
skyboxface = R_RegisterShader("skyboxface", SUF_NONE,
|
||||||
"{\n"
|
"{\n"
|
||||||
"program default2d\n"
|
"program default2d\n"
|
||||||
|
@ -1152,8 +1178,15 @@ static void GL_DrawSkyBox (texid_t *texnums, batch_t *s)
|
||||||
GL_MakeSkyVec (skymaxs[0][i], skymaxs[1][i], i, skyface_vertex[2], skyface_texcoord[2]);
|
GL_MakeSkyVec (skymaxs[0][i], skymaxs[1][i], i, skyface_vertex[2], skyface_texcoord[2]);
|
||||||
GL_MakeSkyVec (skymaxs[0][i], skymins[1][i], i, skyface_vertex[3], skyface_texcoord[3]);
|
GL_MakeSkyVec (skymaxs[0][i], skymins[1][i], i, skyface_vertex[3], skyface_texcoord[3]);
|
||||||
|
|
||||||
skyboxface->defaulttextures->base = texnums[skytexorder[i]];
|
#ifdef MATERIAL_VMT
|
||||||
R_DrawSkyMesh(s, &skyfacemesh, skyboxface);
|
if (!texnums)
|
||||||
|
R_DrawSkyMesh(s, &skyfacemesh, forcedskyfaces[skytexorder[i]]);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
skyboxface->defaulttextures->base = texnums[skytexorder[i]];
|
||||||
|
R_DrawSkyMesh(s, &skyfacemesh, skyboxface);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
!!permu BUMP
|
!!permu BUMP
|
||||||
!!permu SPECULAR
|
!!permu SPECULAR
|
||||||
!!permu REFLECTCUBEMASK
|
!!permu REFLECTCUBEMASK
|
||||||
|
//!!permu TWOWAY //blend between diffuse and the 'upper' texture.
|
||||||
|
//!!permu EIGHTBIT //our fancy software banding.
|
||||||
!!permu FAKESHADOWS
|
!!permu FAKESHADOWS
|
||||||
!!cvarf r_glsl_offsetmapping_scale
|
!!cvarf r_glsl_offsetmapping_scale
|
||||||
!!cvardf r_glsl_pcf
|
!!cvardf r_glsl_pcf
|
||||||
|
@ -16,12 +18,14 @@
|
||||||
!!samps !EIGHTBIT =BUMP normalmap
|
!!samps !EIGHTBIT =BUMP normalmap
|
||||||
!!samps !EIGHTBIT =REFLECTCUBEMASK reflectmask reflectcube
|
!!samps !EIGHTBIT =REFLECTCUBEMASK reflectmask reflectcube
|
||||||
//diffuse gives us alpha, and prevents dlight from bugging out when there's no diffuse.
|
//diffuse gives us alpha, and prevents dlight from bugging out when there's no diffuse.
|
||||||
!!samps =EIGHTBIT paletted 1
|
!!samps =EIGHTBIT colourmap=0
|
||||||
|
!!samps =EIGHTBIT paletted
|
||||||
!!samps =SPECULAR specular
|
!!samps =SPECULAR specular
|
||||||
!!samps !VERTEXLIT lightmap
|
!!samps !VERTEXLIT lightmap
|
||||||
!!samps =LIGHTSTYLED lightmap1 lightmap2 lightmap3
|
!!samps =LIGHTSTYLED lightmap1 lightmap2 lightmap3
|
||||||
!!samps =DELUXE deluxemap
|
!!samps =DELUXE deluxemap
|
||||||
!!samps =LIGHTSTYLED =DELUXE deluxemap1 deluxemap2 deluxemap3
|
!!samps =LIGHTSTYLED =DELUXE deluxemap1 deluxemap2 deluxemap3
|
||||||
|
!!samps =TWOWAY upper
|
||||||
!!samps =FAKESHADOWS shadowmap
|
!!samps =FAKESHADOWS shadowmap
|
||||||
|
|
||||||
#if defined(ORM) || defined(SG)
|
#if defined(ORM) || defined(SG)
|
||||||
|
@ -56,7 +60,9 @@
|
||||||
varying vec2 lm0;
|
varying vec2 lm0;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef TWOWAY
|
||||||
|
varying float alpha;
|
||||||
|
#endif
|
||||||
#ifdef FAKESHADOWS
|
#ifdef FAKESHADOWS
|
||||||
varying vec4 vtexprojcoord;
|
varying vec4 vtexprojcoord;
|
||||||
#endif
|
#endif
|
||||||
|
@ -81,6 +87,9 @@ void main ()
|
||||||
#ifdef FLOW
|
#ifdef FLOW
|
||||||
tc.s += e_time * -0.5;
|
tc.s += e_time * -0.5;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef TWOWAY
|
||||||
|
alpha = v_colour.a;
|
||||||
|
#endif
|
||||||
#ifdef VERTEXLIT
|
#ifdef VERTEXLIT
|
||||||
#ifdef LIGHTSTYLED
|
#ifdef LIGHTSTYLED
|
||||||
//FIXME, only one colour.
|
//FIXME, only one colour.
|
||||||
|
@ -249,7 +258,6 @@ void main()
|
||||||
|
|
||||||
|
|
||||||
#ifdef FRAGMENT_SHADER
|
#ifdef FRAGMENT_SHADER
|
||||||
#define s_colourmap s_t0
|
|
||||||
|
|
||||||
#include "sys/pbr.h"
|
#include "sys/pbr.h"
|
||||||
#include "sys/pcf.h"
|
#include "sys/pcf.h"
|
||||||
|
@ -283,6 +291,11 @@ void main ()
|
||||||
//Read the base texture (with EIGHTBIT only alpha is needed)
|
//Read the base texture (with EIGHTBIT only alpha is needed)
|
||||||
vec4 col = texture2D(s_diffuse, tc);
|
vec4 col = texture2D(s_diffuse, tc);
|
||||||
|
|
||||||
|
#ifdef TWOWAY
|
||||||
|
gl_FragColor *= (1.0-alpha);
|
||||||
|
gl_FragColor += alpha*texture2D(s_upper, tc);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(BUMP) && (defined(DELUXE) || defined(SPECULAR) || defined(REFLECTCUBEMASK))
|
#if defined(BUMP) && (defined(DELUXE) || defined(SPECULAR) || defined(REFLECTCUBEMASK))
|
||||||
vec3 norm = normalize(texture2D(s_normalmap, tc).rgb - 0.5);
|
vec3 norm = normalize(texture2D(s_normalmap, tc).rgb - 0.5);
|
||||||
#elif defined(PBR) || defined(SPECULAR) || defined(DELUXE) || defined(REFLECTCUBEMASK)
|
#elif defined(PBR) || defined(SPECULAR) || defined(DELUXE) || defined(REFLECTCUBEMASK)
|
||||||
|
|
Loading…
Reference in New Issue