2004-10-19 15:56:22 +00:00
|
|
|
/*
|
|
|
|
Copyright (C) 2002-2003 Victor Luchits
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU General Public License
|
|
|
|
as published by the Free Software Foundation; either version 2
|
|
|
|
of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
|
|
|
|
See the GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
|
|
|
|
*/
|
|
|
|
// r_shader.c - based on code by Stephen C. Taylor
|
2010-07-11 02:22:39 +00:00
|
|
|
// Ported to FTE from qfusion, there are numerous changes since then.
|
2004-10-19 15:56:22 +00:00
|
|
|
|
|
|
|
|
|
|
|
#include "quakedef.h"
|
2009-11-04 21:16:50 +00:00
|
|
|
#ifndef SERVERONLY
|
2004-10-19 15:56:22 +00:00
|
|
|
#include "glquake.h"
|
|
|
|
#include "shader.h"
|
|
|
|
|
2004-11-23 01:23:45 +00:00
|
|
|
#include "hash.h"
|
|
|
|
|
2004-10-19 15:56:22 +00:00
|
|
|
|
2004-12-09 23:42:00 +00:00
|
|
|
#include <ctype.h>
|
|
|
|
|
2010-11-11 04:03:16 +00:00
|
|
|
#ifndef GLQUAKE
|
|
|
|
/*the shaders have a few GL_FOO constants in them. they shouldn't, but they do.*/
|
2010-11-10 03:32:47 +00:00
|
|
|
#include <GL/gl.h>
|
|
|
|
#include "glsupp.h"
|
2010-11-11 04:03:16 +00:00
|
|
|
#endif
|
2010-05-01 22:47:47 +00:00
|
|
|
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
extern texid_t missing_texture;
|
|
|
|
static qboolean shader_reload_needed;
|
2010-07-11 02:22:39 +00:00
|
|
|
static qboolean shader_rescan_needed;
|
2004-10-19 15:56:22 +00:00
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
//cvars that affect shader generation
|
|
|
|
cvar_t r_vertexlight = SCVAR("r_vertexlight", "0");
|
2010-07-11 02:22:39 +00:00
|
|
|
extern cvar_t r_fastturb, r_fastsky, r_skyboxname;
|
2009-11-04 21:16:50 +00:00
|
|
|
extern cvar_t r_drawflat;
|
2004-10-19 15:56:22 +00:00
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
//backend fills this in to say the max pass count
|
|
|
|
int be_maxpasses;
|
2004-10-19 15:56:22 +00:00
|
|
|
|
|
|
|
|
|
|
|
#define Q_stricmp stricmp
|
2006-03-06 01:41:09 +00:00
|
|
|
#define Com_sprintf snprintf
|
2004-10-19 15:56:22 +00:00
|
|
|
#define clamp(v,min, max) (v) = (((v)<(min))?(min):(((v)>(max))?(max):(v)));
|
|
|
|
|
|
|
|
typedef union {
|
|
|
|
float f;
|
|
|
|
unsigned int i;
|
|
|
|
} float_int_t;
|
|
|
|
qbyte FloatToByte( float x )
|
|
|
|
{
|
|
|
|
static float_int_t f2i;
|
|
|
|
|
|
|
|
// shift float to have 8bit fraction at base of number
|
|
|
|
f2i.f = x + 32768.0f;
|
|
|
|
|
|
|
|
// then read as integer and kill float bits...
|
|
|
|
return (qbyte) min(f2i.i & 0x7FFFFF, 255);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cvar_t r_detailtextures;
|
|
|
|
|
|
|
|
|
2005-08-26 22:56:51 +00:00
|
|
|
#define MAX_SHADERS 2048 //fixme: this takes a lot of bss in the r_shaders list
|
2004-10-19 15:56:22 +00:00
|
|
|
|
|
|
|
|
|
|
|
#define MAX_TOKEN_CHARS 1024
|
|
|
|
|
|
|
|
char *COM_ParseExt (char **data_p, qboolean nl)
|
|
|
|
{
|
|
|
|
int c;
|
|
|
|
int len;
|
|
|
|
char *data;
|
|
|
|
qboolean newlines = false;
|
|
|
|
|
|
|
|
data = *data_p;
|
|
|
|
len = 0;
|
|
|
|
com_token[0] = 0;
|
|
|
|
|
|
|
|
if (!data)
|
|
|
|
{
|
|
|
|
*data_p = NULL;
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
// skip whitespace
|
|
|
|
skipwhite:
|
2009-11-04 21:16:50 +00:00
|
|
|
while ((c = *data) <= ' ')
|
2004-10-19 15:56:22 +00:00
|
|
|
{
|
|
|
|
if (c == 0)
|
|
|
|
{
|
|
|
|
*data_p = NULL;
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
if (c == '\n')
|
|
|
|
newlines = true;
|
|
|
|
data++;
|
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
if (newlines && !nl)
|
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
*data_p = data;
|
|
|
|
return com_token;
|
|
|
|
}
|
|
|
|
|
|
|
|
// skip // comments
|
|
|
|
if (c == '/' && data[1] == '/')
|
|
|
|
{
|
|
|
|
while (*data && *data != '\n')
|
|
|
|
data++;
|
|
|
|
goto skipwhite;
|
|
|
|
}
|
|
|
|
|
|
|
|
// handle quoted strings specially
|
|
|
|
if (c == '\"')
|
|
|
|
{
|
|
|
|
data++;
|
|
|
|
while (1)
|
|
|
|
{
|
|
|
|
c = *data++;
|
|
|
|
if (c=='\"' || !c)
|
|
|
|
{
|
|
|
|
com_token[len] = 0;
|
|
|
|
*data_p = data;
|
|
|
|
return com_token;
|
|
|
|
}
|
|
|
|
if (len < MAX_TOKEN_CHARS)
|
|
|
|
{
|
|
|
|
com_token[len] = c;
|
|
|
|
len++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// parse a regular word
|
|
|
|
do
|
|
|
|
{
|
|
|
|
if (len < MAX_TOKEN_CHARS)
|
|
|
|
{
|
|
|
|
com_token[len] = c;
|
|
|
|
len++;
|
|
|
|
}
|
|
|
|
data++;
|
|
|
|
c = *data;
|
|
|
|
} while (c>32);
|
|
|
|
|
|
|
|
if (len == MAX_TOKEN_CHARS)
|
|
|
|
{
|
|
|
|
// Com_Printf ("Token exceeded %i chars, discarded.\n", MAX_TOKEN_CHARS);
|
|
|
|
len = 0;
|
|
|
|
}
|
|
|
|
com_token[len] = 0;
|
|
|
|
|
|
|
|
*data_p = data;
|
|
|
|
return com_token;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define HASH_SIZE 128
|
|
|
|
|
|
|
|
typedef struct shaderkey_s
|
|
|
|
{
|
|
|
|
char *keyword;
|
|
|
|
void (*func)( shader_t *shader, shaderpass_t *pass, char **ptr );
|
|
|
|
} shaderkey_t;
|
|
|
|
|
|
|
|
typedef struct shadercache_s {
|
|
|
|
char name[MAX_QPATH];
|
|
|
|
char *path;
|
|
|
|
unsigned int offset;
|
|
|
|
struct shadercache_s *hash_next;
|
|
|
|
} shadercache_t;
|
|
|
|
|
2010-05-01 22:47:47 +00:00
|
|
|
static shadercache_t **shader_hash;
|
2005-03-28 00:11:59 +00:00
|
|
|
static char shaderbuf[MAX_QPATH * 256];
|
|
|
|
int shaderbuflen;
|
2004-10-19 15:56:22 +00:00
|
|
|
|
2010-05-01 22:47:47 +00:00
|
|
|
shader_t *r_shaders;
|
2010-07-11 02:22:39 +00:00
|
|
|
static hashtable_t shader_active_hash;
|
|
|
|
void *shader_active_hash_mem;
|
2004-10-19 15:56:22 +00:00
|
|
|
|
2004-12-09 23:42:00 +00:00
|
|
|
//static char r_skyboxname[MAX_QPATH];
|
|
|
|
//static float r_skyheight;
|
2004-10-19 15:56:22 +00:00
|
|
|
|
|
|
|
char *Shader_Skip( char *ptr );
|
|
|
|
static qboolean Shader_Parsetok( shader_t *shader, shaderpass_t *pass, shaderkey_t *keys,
|
|
|
|
char *token, char **ptr );
|
|
|
|
static void Shader_ParseFunc( char **args, shaderfunc_t *func );
|
|
|
|
static void Shader_MakeCache( char *path );
|
|
|
|
static void Shader_GetPathAndOffset( char *name, char **path, unsigned int *offset );
|
2009-11-04 21:16:50 +00:00
|
|
|
static void Shader_ReadShader(shader_t *s, char *shadersource);
|
2004-10-19 15:56:22 +00:00
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
|
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
|
|
|
static qboolean Shader_EvaluateCondition(char **ptr)
|
|
|
|
{
|
|
|
|
char *token;
|
|
|
|
cvar_t *cv;
|
|
|
|
qboolean conditiontrue = true;
|
|
|
|
token = COM_ParseExt ( ptr, false );
|
|
|
|
if (*token == '!')
|
|
|
|
{
|
|
|
|
conditiontrue = false;
|
|
|
|
token++;
|
|
|
|
}
|
|
|
|
if (*token == '$')
|
|
|
|
{
|
|
|
|
extern cvar_t gl_bump;
|
|
|
|
token++;
|
|
|
|
if (!Q_stricmp(token, "lightmap"))
|
|
|
|
conditiontrue = conditiontrue == !r_fullbright.value;
|
|
|
|
else if (!Q_stricmp(token, "deluxmap") )
|
|
|
|
conditiontrue = conditiontrue == !!gl_bump.value;
|
|
|
|
|
|
|
|
//normalmaps are generated if they're not already known.
|
|
|
|
else if (!Q_stricmp(token, "normalmap") )
|
|
|
|
conditiontrue = conditiontrue == !!gl_bump.value;
|
|
|
|
|
|
|
|
#pragma message("shader fixme")
|
|
|
|
else if (!Q_stricmp(token, "diffuse") )
|
|
|
|
conditiontrue = conditiontrue == true;
|
|
|
|
else if (!Q_stricmp(token, "specular") )
|
|
|
|
conditiontrue = conditiontrue == false;
|
|
|
|
else if (!Q_stricmp(token, "fullbright") )
|
|
|
|
conditiontrue = conditiontrue == false;
|
|
|
|
else if (!Q_stricmp(token, "topoverlay") )
|
|
|
|
conditiontrue = conditiontrue == false;
|
|
|
|
else if (!Q_stricmp(token, "loweroverlay") )
|
|
|
|
conditiontrue = conditiontrue == false;
|
|
|
|
|
|
|
|
else
|
|
|
|
conditiontrue = conditiontrue == false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
cv = Cvar_Get(token, "", 0, "Shader Conditions");
|
2010-11-10 03:32:47 +00:00
|
|
|
token = COM_ParseExt ( ptr, false );
|
|
|
|
if (*token)
|
|
|
|
{
|
|
|
|
float rhs;
|
|
|
|
char cmp[4];
|
|
|
|
memcpy(cmp, token, 4);
|
|
|
|
token = COM_ParseExt ( ptr, false );
|
|
|
|
rhs = atof(token);
|
|
|
|
if (!strcmp(cmp, "!="))
|
|
|
|
conditiontrue = cv->value != rhs;
|
|
|
|
else if (!strcmp(cmp, "=="))
|
|
|
|
conditiontrue = cv->value == rhs;
|
|
|
|
else if (!strcmp(cmp, "<"))
|
|
|
|
conditiontrue = cv->value < rhs;
|
|
|
|
else if (!strcmp(cmp, "<="))
|
|
|
|
conditiontrue = cv->value <= rhs;
|
|
|
|
else if (!strcmp(cmp, ">"))
|
|
|
|
conditiontrue = cv->value > rhs;
|
|
|
|
else if (!strcmp(cmp, ">="))
|
|
|
|
conditiontrue = cv->value >= rhs;
|
|
|
|
else
|
|
|
|
conditiontrue = false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (cv)
|
|
|
|
conditiontrue = conditiontrue == !!cv->value;
|
|
|
|
}
|
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return conditiontrue;
|
|
|
|
}
|
|
|
|
|
2004-10-19 15:56:22 +00:00
|
|
|
static char *Shader_ParseString ( char **ptr )
|
|
|
|
{
|
|
|
|
char *token;
|
|
|
|
|
|
|
|
if ( !ptr || !(*ptr) ) {
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
if ( !**ptr || **ptr == '}' ) {
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
token = COM_ParseExt ( ptr, false );
|
2005-01-24 23:47:32 +00:00
|
|
|
Q_strlwr ( token );
|
2004-10-19 15:56:22 +00:00
|
|
|
|
|
|
|
return token;
|
|
|
|
}
|
|
|
|
|
2010-07-11 02:22:39 +00:00
|
|
|
static char *Shader_ParseSensString ( char **ptr )
|
|
|
|
{
|
|
|
|
char *token;
|
|
|
|
|
|
|
|
if ( !ptr || !(*ptr) ) {
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
if ( !**ptr || **ptr == '}' ) {
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
token = COM_ParseExt ( ptr, false );
|
|
|
|
|
|
|
|
return token;
|
|
|
|
}
|
|
|
|
|
2004-10-19 15:56:22 +00:00
|
|
|
static float Shader_ParseFloat ( char **ptr )
|
|
|
|
{
|
|
|
|
if ( !ptr || !(*ptr) ) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if ( !**ptr || **ptr == '}' ) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return atof ( COM_ParseExt ( ptr, false ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
static void Shader_ParseVector ( char **ptr, vec3_t v )
|
|
|
|
{
|
2009-11-04 21:16:50 +00:00
|
|
|
char *scratch;
|
2004-10-19 15:56:22 +00:00
|
|
|
char *token;
|
|
|
|
qboolean bracket;
|
|
|
|
|
|
|
|
token = Shader_ParseString ( ptr );
|
2009-11-04 21:16:50 +00:00
|
|
|
if (*token == '$')
|
|
|
|
{
|
|
|
|
cvar_t *var;
|
|
|
|
var = Cvar_FindVar(token+1);
|
|
|
|
if (!var)
|
|
|
|
{
|
|
|
|
v[0] = 1;
|
|
|
|
v[1] = 1;
|
|
|
|
v[2] = 1;
|
|
|
|
return;
|
|
|
|
}
|
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
|
|
|
var->flags |= CVAR_SHADERSYSTEM;
|
2009-11-04 21:16:50 +00:00
|
|
|
ptr = &scratch;
|
|
|
|
scratch = var->string;
|
2010-07-11 02:22:39 +00:00
|
|
|
|
|
|
|
token = Shader_ParseString ( ptr );
|
2009-11-04 21:16:50 +00:00
|
|
|
}
|
2004-10-19 15:56:22 +00:00
|
|
|
if ( !Q_stricmp (token, "(") ) {
|
|
|
|
bracket = true;
|
|
|
|
token = Shader_ParseString ( ptr );
|
|
|
|
} else if ( token[0] == '(' ) {
|
|
|
|
bracket = true;
|
|
|
|
token = &token[1];
|
|
|
|
} else {
|
|
|
|
bracket = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
v[0] = atof ( token );
|
|
|
|
v[1] = Shader_ParseFloat ( ptr );
|
|
|
|
|
|
|
|
token = Shader_ParseString ( ptr );
|
|
|
|
if ( !token[0] ) {
|
|
|
|
v[2] = 0;
|
|
|
|
} else if ( token[strlen(token)-1] == ')' ) {
|
|
|
|
token[strlen(token)-1] = 0;
|
|
|
|
v[2] = atof ( token );
|
|
|
|
} else {
|
|
|
|
v[2] = atof ( token );
|
|
|
|
if ( bracket ) {
|
|
|
|
Shader_ParseString ( ptr );
|
|
|
|
}
|
|
|
|
}
|
2009-11-04 21:16:50 +00:00
|
|
|
|
|
|
|
if (v[0] > 5 || v[1] > 5 || v[2] > 5)
|
|
|
|
{
|
|
|
|
VectorScale(v, 1.0f/255, v);
|
|
|
|
}
|
2004-10-19 15:56:22 +00:00
|
|
|
}
|
|
|
|
|
2010-07-11 02:22:39 +00:00
|
|
|
qboolean Shader_ParseSkySides (char *shadername, char *texturename, texid_t *images)
|
2004-10-19 15:56:22 +00:00
|
|
|
{
|
2010-07-11 02:22:39 +00:00
|
|
|
qboolean allokay = true;
|
2009-11-04 21:16:50 +00:00
|
|
|
int i, ss, sp;
|
2004-10-19 15:56:22 +00:00
|
|
|
char path[MAX_QPATH];
|
2009-11-04 21:16:50 +00:00
|
|
|
|
|
|
|
static char *skyname_suffix[][6] = {
|
|
|
|
{"rt", "bk", "lf", "ft", "up", "dn"},
|
|
|
|
{"px", "py", "nx", "ny", "pz", "nz"},
|
|
|
|
{"posx", "posy", "negx", "negy", "posz", "negz"},
|
|
|
|
{"_px", "_py", "_nx", "_ny", "_pz", "_nz"},
|
|
|
|
{"_posx", "_posy", "_negx", "_negy", "_posz", "_negz"},
|
|
|
|
{"_rt", "_bk", "_lf", "_ft", "_up", "_dn"}
|
|
|
|
};
|
|
|
|
|
|
|
|
static char *skyname_pattern[] = {
|
|
|
|
"%s_%s",
|
|
|
|
"%s%s",
|
|
|
|
"env/%s%s",
|
|
|
|
"gfx/env/%s%s"
|
|
|
|
};
|
2004-10-19 15:56:22 +00:00
|
|
|
|
2010-07-11 02:22:39 +00:00
|
|
|
if (*texturename == '$')
|
2009-11-04 21:16:50 +00:00
|
|
|
{
|
|
|
|
cvar_t *v;
|
2010-07-11 02:22:39 +00:00
|
|
|
v = Cvar_FindVar(texturename+1);
|
2009-11-04 21:16:50 +00:00
|
|
|
if (v)
|
2010-07-11 02:22:39 +00:00
|
|
|
texturename = v->string;
|
2009-11-04 21:16:50 +00:00
|
|
|
}
|
2010-07-11 02:22:39 +00:00
|
|
|
if (!*texturename)
|
|
|
|
texturename = "-";
|
|
|
|
|
2004-10-19 15:56:22 +00:00
|
|
|
for ( i = 0; i < 6; i++ )
|
|
|
|
{
|
2010-07-11 02:22:39 +00:00
|
|
|
if ( texturename[0] == '-' )
|
|
|
|
{
|
2009-11-04 21:16:50 +00:00
|
|
|
images[i] = r_nulltex;
|
2010-07-11 02:22:39 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-11-04 21:16:50 +00:00
|
|
|
for (sp = 0; sp < sizeof(skyname_pattern)/sizeof(skyname_pattern[0]); sp++)
|
|
|
|
{
|
|
|
|
for (ss = 0; ss < sizeof(skyname_suffix)/sizeof(skyname_suffix[0]); ss++)
|
|
|
|
{
|
2010-07-11 02:22:39 +00:00
|
|
|
Com_sprintf ( path, sizeof(path), skyname_pattern[sp], texturename, skyname_suffix[ss][i] );
|
2009-11-04 21:16:50 +00:00
|
|
|
images[i] = R_LoadHiResTexture ( path, NULL, IF_NOALPHA);
|
|
|
|
if (TEXVALID(images[i]))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (TEXVALID(images[i]))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (!TEXVALID(images[i]))
|
2009-01-15 04:58:12 +00:00
|
|
|
{
|
2010-07-11 02:22:39 +00:00
|
|
|
Con_Printf("Sky \"%s\" missing texture: %s\n", shadername, path);
|
2006-01-12 22:24:06 +00:00
|
|
|
images[i] = missing_texture;
|
2010-07-11 02:22:39 +00:00
|
|
|
allokay = false;
|
2009-01-15 04:58:12 +00:00
|
|
|
}
|
2004-10-19 15:56:22 +00:00
|
|
|
}
|
|
|
|
}
|
2010-07-11 02:22:39 +00:00
|
|
|
return allokay;
|
2004-10-19 15:56:22 +00:00
|
|
|
}
|
2005-04-16 16:21:27 +00:00
|
|
|
|
2004-10-19 15:56:22 +00:00
|
|
|
static void Shader_ParseFunc ( char **ptr, shaderfunc_t *func )
|
|
|
|
{
|
|
|
|
char *token;
|
|
|
|
|
|
|
|
token = Shader_ParseString ( ptr );
|
|
|
|
if ( !Q_stricmp (token, "sin") ) {
|
|
|
|
func->type = SHADER_FUNC_SIN;
|
|
|
|
} else if ( !Q_stricmp (token, "triangle") ) {
|
|
|
|
func->type = SHADER_FUNC_TRIANGLE;
|
|
|
|
} else if ( !Q_stricmp (token, "square") ) {
|
|
|
|
func->type = SHADER_FUNC_SQUARE;
|
|
|
|
} else if ( !Q_stricmp (token, "sawtooth") ) {
|
|
|
|
func->type = SHADER_FUNC_SAWTOOTH;
|
|
|
|
} else if (!Q_stricmp (token, "inversesawtooth") ) {
|
|
|
|
func->type = SHADER_FUNC_INVERSESAWTOOTH;
|
|
|
|
} else if (!Q_stricmp (token, "noise") ) {
|
|
|
|
func->type = SHADER_FUNC_NOISE;
|
|
|
|
}
|
|
|
|
|
|
|
|
func->args[0] = Shader_ParseFloat ( ptr );
|
|
|
|
func->args[1] = Shader_ParseFloat ( ptr );
|
|
|
|
func->args[2] = Shader_ParseFloat ( ptr );
|
|
|
|
func->args[3] = Shader_ParseFloat ( ptr );
|
|
|
|
}
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
|
|
|
|
static int Shader_SetImageFlags ( shader_t *shader )
|
|
|
|
{
|
|
|
|
int flags = 0;
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
// if (shader->flags & SHADER_SKY)
|
|
|
|
// flags |= IF_SKY;
|
|
|
|
if (shader->flags & SHADER_NOMIPMAPS)
|
|
|
|
flags |= IF_NOMIPMAP;
|
|
|
|
if (shader->flags & SHADER_NOPICMIP)
|
|
|
|
flags |= IF_NOPICMIP;
|
2004-10-19 15:56:22 +00:00
|
|
|
|
|
|
|
return flags;
|
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
static texid_t Shader_FindImage ( char *name, int flags )
|
2004-10-19 15:56:22 +00:00
|
|
|
{
|
2009-11-04 21:16:50 +00:00
|
|
|
if (!Q_stricmp (name, "$whiteimage"))
|
|
|
|
return r_nulltex;
|
|
|
|
else
|
|
|
|
return R_LoadHiResTexture(name, NULL, flags);
|
2004-10-19 15:56:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/****************** shader keyword functions ************************/
|
|
|
|
|
|
|
|
static void Shader_Cull ( shader_t *shader, shaderpass_t *pass, char **ptr )
|
|
|
|
{
|
|
|
|
char *token;
|
|
|
|
|
|
|
|
shader->flags &= ~(SHADER_CULL_FRONT|SHADER_CULL_BACK);
|
|
|
|
|
|
|
|
token = Shader_ParseString ( ptr );
|
|
|
|
if ( !Q_stricmp (token, "disable") || !Q_stricmp (token, "none") || !Q_stricmp (token, "twosided") ) {
|
|
|
|
} else if ( !Q_stricmp (token, "front") ) {
|
|
|
|
shader->flags |= SHADER_CULL_FRONT;
|
|
|
|
} else if ( !Q_stricmp (token, "back") || !Q_stricmp (token, "backside") || !Q_stricmp (token, "backsided") ) {
|
|
|
|
shader->flags |= SHADER_CULL_BACK;
|
|
|
|
} else {
|
|
|
|
shader->flags |= SHADER_CULL_FRONT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void Shader_NoMipMaps ( shader_t *shader, shaderpass_t *pass, char **ptr )
|
|
|
|
{
|
|
|
|
shader->flags |= (SHADER_NOMIPMAPS|SHADER_NOPICMIP);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void Shader_NoPicMip ( shader_t *shader, shaderpass_t *pass, char **ptr )
|
|
|
|
{
|
|
|
|
shader->flags |= SHADER_NOPICMIP;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void Shader_DeformVertexes ( shader_t *shader, shaderpass_t *pass, char **ptr )
|
|
|
|
{
|
|
|
|
char *token;
|
|
|
|
deformv_t *deformv;
|
|
|
|
|
|
|
|
if ( shader->numdeforms >= SHADER_DEFORM_MAX ) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
deformv = &shader->deforms[shader->numdeforms];
|
|
|
|
|
|
|
|
token = Shader_ParseString ( ptr );
|
|
|
|
if ( !Q_stricmp (token, "wave") ) {
|
|
|
|
deformv->type = DEFORMV_WAVE;
|
|
|
|
deformv->args[0] = Shader_ParseFloat ( ptr );
|
|
|
|
if ( deformv->args[0] ) {
|
|
|
|
deformv->args[0] = 1.0f / deformv->args[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
Shader_ParseFunc ( ptr, &deformv->func );
|
|
|
|
} else if ( !Q_stricmp (token, "normal") ) {
|
|
|
|
deformv->type = DEFORMV_NORMAL;
|
|
|
|
deformv->args[0] = Shader_ParseFloat ( ptr );
|
|
|
|
deformv->args[1] = Shader_ParseFloat ( ptr );
|
|
|
|
} else if ( !Q_stricmp (token, "bulge") ) {
|
|
|
|
deformv->type = DEFORMV_BULGE;
|
|
|
|
|
|
|
|
Shader_ParseVector ( ptr, deformv->args );
|
|
|
|
shader->flags |= SHADER_DEFORMV_BULGE;
|
|
|
|
} else if ( !Q_stricmp (token, "move") ) {
|
|
|
|
deformv->type = DEFORMV_MOVE;
|
|
|
|
|
|
|
|
Shader_ParseVector ( ptr, deformv->args );
|
|
|
|
Shader_ParseFunc ( ptr, &deformv->func );
|
|
|
|
} else if ( !Q_stricmp (token, "autosprite") ) {
|
|
|
|
deformv->type = DEFORMV_AUTOSPRITE;
|
|
|
|
shader->flags |= SHADER_AUTOSPRITE;
|
|
|
|
} else if ( !Q_stricmp (token, "autosprite2") ) {
|
|
|
|
deformv->type = DEFORMV_AUTOSPRITE2;
|
|
|
|
shader->flags |= SHADER_AUTOSPRITE;
|
|
|
|
} else if ( !Q_stricmp (token, "projectionShadow") ) {
|
|
|
|
deformv->type = DEFORMV_PROJECTION_SHADOW;
|
|
|
|
} else {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
shader->numdeforms++;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-07-11 02:22:39 +00:00
|
|
|
static void Shader_SkyParms(shader_t *shader, shaderpass_t *pass, char **ptr)
|
2004-10-19 15:56:22 +00:00
|
|
|
{
|
2005-04-16 16:21:27 +00:00
|
|
|
int i;
|
2004-10-19 15:56:22 +00:00
|
|
|
skydome_t *skydome;
|
|
|
|
float skyheight;
|
2010-07-11 02:22:39 +00:00
|
|
|
char *boxname;
|
2004-10-19 15:56:22 +00:00
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
if (shader->skydome)
|
|
|
|
{
|
2010-07-11 02:22:39 +00:00
|
|
|
for (i = 0; i < 5; i++)
|
|
|
|
{
|
|
|
|
Z_Free(shader->skydome->meshes[i].xyz_array);
|
|
|
|
Z_Free(shader->skydome->meshes[i].normals_array);
|
|
|
|
Z_Free(shader->skydome->meshes[i].st_array);
|
2004-10-19 15:56:22 +00:00
|
|
|
}
|
|
|
|
|
2010-07-11 02:22:39 +00:00
|
|
|
Z_Free(shader->skydome);
|
2004-10-19 15:56:22 +00:00
|
|
|
}
|
|
|
|
|
2010-07-11 02:22:39 +00:00
|
|
|
skydome = (skydome_t *)Z_Malloc(sizeof(skydome_t));
|
2004-10-19 15:56:22 +00:00
|
|
|
shader->skydome = skydome;
|
|
|
|
|
2010-07-11 02:22:39 +00:00
|
|
|
boxname = Shader_ParseString(ptr);
|
|
|
|
Shader_ParseSkySides(shader->name, boxname, skydome->farbox_textures);
|
2004-10-19 15:56:22 +00:00
|
|
|
|
2010-07-11 02:22:39 +00:00
|
|
|
skyheight = Shader_ParseFloat(ptr);
|
|
|
|
if (!skyheight)
|
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
skyheight = 512.0f;
|
|
|
|
}
|
|
|
|
|
2010-07-11 02:22:39 +00:00
|
|
|
boxname = Shader_ParseString(ptr);
|
|
|
|
Shader_ParseSkySides(shader->name, boxname, skydome->nearbox_textures);
|
2004-10-19 15:56:22 +00:00
|
|
|
|
|
|
|
shader->flags |= SHADER_SKY;
|
|
|
|
shader->sort = SHADER_SORT_SKY;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void Shader_FogParms ( shader_t *shader, shaderpass_t *pass, char **ptr )
|
|
|
|
{
|
|
|
|
float div;
|
|
|
|
vec3_t color, fcolor;
|
|
|
|
|
|
|
|
// if ( !r_ignorehwgamma->value )
|
|
|
|
// div = 1.0f / pow(2, max(0, floor(r_overbrightbits->value)));
|
|
|
|
// else
|
|
|
|
div = 1.0f;
|
|
|
|
|
|
|
|
Shader_ParseVector ( ptr, color );
|
|
|
|
VectorScale ( color, div, color );
|
|
|
|
ColorNormalize ( color, fcolor );
|
|
|
|
|
|
|
|
shader->fog_color[0] = FloatToByte ( fcolor[0] );
|
|
|
|
shader->fog_color[1] = FloatToByte ( fcolor[1] );
|
|
|
|
shader->fog_color[2] = FloatToByte ( fcolor[2] );
|
|
|
|
shader->fog_color[3] = 255;
|
|
|
|
shader->fog_dist = Shader_ParseFloat ( ptr );
|
|
|
|
|
|
|
|
if ( shader->fog_dist <= 0.0f ) {
|
|
|
|
shader->fog_dist = 128.0f;
|
|
|
|
}
|
|
|
|
shader->fog_dist = 1.0f / shader->fog_dist;
|
|
|
|
}
|
|
|
|
|
2005-05-26 12:55:34 +00:00
|
|
|
static void Shader_SurfaceParm ( shader_t *shader, shaderpass_t *pass, char **ptr )
|
|
|
|
{
|
|
|
|
char *token;
|
|
|
|
|
|
|
|
token = Shader_ParseString ( ptr );
|
|
|
|
if ( !Q_stricmp( token, "nodraw" ) )
|
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
|
|
|
shader->flags |= SHADER_NODRAW;
|
2009-11-04 21:16:50 +00:00
|
|
|
else if ( !Q_stricmp( token, "nodlight" ) )
|
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
|
|
|
shader->flags |= SHADER_NODLIGHT;
|
2005-05-26 12:55:34 +00:00
|
|
|
}
|
|
|
|
|
2004-10-19 15:56:22 +00:00
|
|
|
static void Shader_Sort ( shader_t *shader, shaderpass_t *pass, char **ptr )
|
|
|
|
{
|
|
|
|
char *token;
|
|
|
|
|
|
|
|
token = Shader_ParseString ( ptr );
|
|
|
|
if ( !Q_stricmp( token, "portal" ) ) {
|
|
|
|
shader->sort = SHADER_SORT_PORTAL;
|
|
|
|
} else if( !Q_stricmp( token, "sky" ) ) {
|
|
|
|
shader->sort = SHADER_SORT_SKY;
|
|
|
|
} else if( !Q_stricmp( token, "opaque" ) ) {
|
|
|
|
shader->sort = SHADER_SORT_OPAQUE;
|
2010-07-11 02:22:39 +00:00
|
|
|
} else if( !Q_stricmp( token, "decal" ) ) {
|
|
|
|
shader->sort = SHADER_SORT_DECAL;
|
|
|
|
} else if( !Q_stricmp( token, "seethrough" ) ) {
|
|
|
|
shader->sort = SHADER_SORT_SEETHROUGH;
|
2004-10-19 15:56:22 +00:00
|
|
|
} else if( !Q_stricmp( token, "banner" ) ) {
|
|
|
|
shader->sort = SHADER_SORT_BANNER;
|
|
|
|
} else if( !Q_stricmp( token, "additive" ) ) {
|
|
|
|
shader->sort = SHADER_SORT_ADDITIVE;
|
2010-07-11 02:22:39 +00:00
|
|
|
} else if( !Q_stricmp( token, "underwater" ) ) {
|
|
|
|
shader->sort = SHADER_SORT_UNDERWATER;
|
2004-10-19 15:56:22 +00:00
|
|
|
} else if( !Q_stricmp( token, "nearest" ) ) {
|
|
|
|
shader->sort = SHADER_SORT_NEAREST;
|
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
|
|
|
} else if( !Q_stricmp( token, "blend" ) ) {
|
|
|
|
shader->sort = SHADER_SORT_BLEND;
|
2004-10-19 15:56:22 +00:00
|
|
|
} else {
|
|
|
|
shader->sort = atoi ( token );
|
|
|
|
clamp ( shader->sort, SHADER_SORT_NONE, SHADER_SORT_NEAREST );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void Shader_Portal ( shader_t *shader, shaderpass_t *pass, char **ptr )
|
|
|
|
{
|
|
|
|
shader->sort = SHADER_SORT_PORTAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void Shader_PolygonOffset ( shader_t *shader, shaderpass_t *pass, char **ptr )
|
|
|
|
{
|
2009-11-04 21:16:50 +00:00
|
|
|
/*the q3 defaults*/
|
|
|
|
shader->polyoffset.factor = -0.05;
|
|
|
|
shader->polyoffset.unit = -25;
|
2004-10-19 15:56:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void Shader_EntityMergable ( shader_t *shader, shaderpass_t *pass, char **ptr )
|
|
|
|
{
|
|
|
|
shader->flags |= SHADER_ENTITY_MERGABLE;
|
|
|
|
}
|
|
|
|
|
2010-08-28 17:14:38 +00:00
|
|
|
static void Shader_LoadProgram(shader_t *shader, char *vert, char *frag, int qrtype)
|
|
|
|
{
|
|
|
|
static char *permutationdefines[PERMUTATIONS] = {
|
|
|
|
"",
|
|
|
|
"#define BUMP\n",
|
|
|
|
"#define SPECULAR\n",
|
|
|
|
"#define SPECULAR\n#define BUMP\n",
|
|
|
|
"#define USEOFFSETMAPPING\n",
|
|
|
|
"#define USEOFFSETMAPPING\n#define BUMP\n",
|
|
|
|
"#define USEOFFSETMAPPING\n#define SPECULAR\n",
|
|
|
|
"#define USEOFFSETMAPPING\n#define SPECULAR\n#define BUMP\n"
|
|
|
|
};
|
|
|
|
int p;
|
|
|
|
|
|
|
|
if (!frag)
|
|
|
|
frag = vert;
|
|
|
|
|
|
|
|
for (p = 0; p < PERMUTATIONS; p++)
|
|
|
|
{
|
|
|
|
if (qrenderer != qrtype)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
#ifdef GLQUAKE
|
|
|
|
else if (qrenderer == QR_OPENGL)
|
|
|
|
shader->programhandle[p].glsl = GLSlang_CreateProgram(permutationdefines[p], (char *)vert, (char *)frag);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
static void Shader_SLProgramName (shader_t *shader, shaderpass_t *pass, char **ptr, int qrtype)
|
2006-03-11 03:12:10 +00:00
|
|
|
{
|
2010-07-11 02:22:39 +00:00
|
|
|
/*accepts:
|
|
|
|
program
|
|
|
|
{
|
|
|
|
BLAH
|
|
|
|
}
|
|
|
|
where BLAH is both vertex+frag with #ifdefs
|
|
|
|
or
|
|
|
|
program vert frag
|
|
|
|
on one line.
|
|
|
|
*/
|
2006-04-16 03:55:55 +00:00
|
|
|
void *vert, *frag;
|
2006-03-11 03:12:10 +00:00
|
|
|
char *token;
|
2009-07-05 18:45:53 +00:00
|
|
|
|
|
|
|
token = *ptr;
|
|
|
|
while (*token == ' ' || *token == '\t' || *token == '\r')
|
|
|
|
token++;
|
|
|
|
if (*token == '\n')
|
|
|
|
{
|
|
|
|
int count;
|
|
|
|
token++;
|
|
|
|
while (*token == ' ' || *token == '\t')
|
|
|
|
token++;
|
|
|
|
if (*token != '{')
|
|
|
|
{
|
|
|
|
Con_Printf("shader \"%s\" missing program string\n", shader->name);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
token++;
|
2010-08-28 17:14:38 +00:00
|
|
|
frag = token;
|
2009-07-05 18:45:53 +00:00
|
|
|
for (count = 1; *token; token++)
|
|
|
|
{
|
|
|
|
if (*token == '}')
|
|
|
|
{
|
|
|
|
count--;
|
|
|
|
if (!count)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else if (*token == '{')
|
|
|
|
count++;
|
|
|
|
}
|
2010-08-28 17:14:38 +00:00
|
|
|
vert = BZ_Malloc(token - (char*)frag + 1);
|
|
|
|
memcpy(vert, frag, token-(char*)frag);
|
|
|
|
((char*)vert)[token-(char*)frag] = 0;
|
|
|
|
frag = NULL;
|
2009-07-05 18:45:53 +00:00
|
|
|
*ptr = token+1;
|
|
|
|
|
2010-08-28 17:14:38 +00:00
|
|
|
Shader_LoadProgram(shader, vert, frag, qrtype);
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
BZ_Free(vert);
|
2009-07-05 18:45:53 +00:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-08-28 17:14:38 +00:00
|
|
|
vert = Shader_ParseString(ptr);
|
|
|
|
if (!strcmp(vert, "default"))
|
2009-11-04 21:16:50 +00:00
|
|
|
{
|
2010-08-28 17:14:38 +00:00
|
|
|
extern char *defaultglsl2program;
|
|
|
|
frag = Shader_ParseString(ptr);
|
2010-11-02 23:17:25 +00:00
|
|
|
#ifdef GLQUAKE
|
|
|
|
if (qrenderer == QR_OPENGL)
|
|
|
|
Shader_LoadProgram(shader, defaultglsl2program, defaultglsl2program, qrtype);
|
|
|
|
#endif
|
2010-08-28 17:14:38 +00:00
|
|
|
return;
|
2009-11-04 21:16:50 +00:00
|
|
|
}
|
2010-08-28 17:14:38 +00:00
|
|
|
FS_LoadFile(vert, &vert);
|
|
|
|
|
|
|
|
frag = Shader_ParseString(ptr);
|
|
|
|
if (!frag)
|
|
|
|
frag = NULL;
|
|
|
|
else
|
|
|
|
FS_LoadFile(frag, &frag);
|
|
|
|
|
|
|
|
Shader_LoadProgram(shader, vert, frag, qrtype);
|
2006-03-11 03:12:10 +00:00
|
|
|
if (vert)
|
|
|
|
FS_FreeFile(vert);
|
|
|
|
if (frag)
|
|
|
|
FS_FreeFile(frag);
|
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
static void Shader_GLSLProgramName (shader_t *shader, shaderpass_t *pass, char **ptr)
|
|
|
|
{
|
|
|
|
Shader_SLProgramName(shader,pass,ptr,QR_OPENGL);
|
|
|
|
}
|
|
|
|
static void Shader_HLSLProgramName (shader_t *shader, shaderpass_t *pass, char **ptr)
|
|
|
|
{
|
|
|
|
Shader_SLProgramName(shader,pass,ptr,QR_DIRECT3D);
|
|
|
|
}
|
|
|
|
|
2006-03-11 03:12:10 +00:00
|
|
|
static void Shader_ProgramParam ( shader_t *shader, shaderpass_t *pass, char **ptr )
|
|
|
|
{
|
2010-08-28 17:14:38 +00:00
|
|
|
cvar_t *cv = NULL;
|
2006-03-11 03:12:10 +00:00
|
|
|
int specialint = 0;
|
|
|
|
float specialfloat = 0;
|
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
|
|
|
vec3_t specialvec = {0};
|
2006-03-11 03:12:10 +00:00
|
|
|
enum shaderprogparmtype_e parmtype = SP_BAD;
|
|
|
|
char *token;
|
2009-11-04 21:16:50 +00:00
|
|
|
qboolean silent = false;
|
2006-03-11 03:12:10 +00:00
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
token = Shader_ParseString(ptr);
|
|
|
|
if (!Q_stricmp(token, "opt"))
|
|
|
|
{
|
|
|
|
silent = true;
|
|
|
|
token = Shader_ParseString(ptr);
|
|
|
|
}
|
2006-03-11 03:12:10 +00:00
|
|
|
if (!Q_stricmp(token, "texture"))
|
|
|
|
{
|
2009-11-04 21:16:50 +00:00
|
|
|
token = Shader_ParseString(ptr);
|
2006-03-11 03:12:10 +00:00
|
|
|
specialint = atoi(token);
|
|
|
|
parmtype = SP_TEXTURE;
|
|
|
|
}
|
2010-11-10 03:32:47 +00:00
|
|
|
else if (!Q_stricmp(token, "consti"))
|
|
|
|
{
|
|
|
|
token = Shader_ParseSensString(ptr);
|
|
|
|
specialint = atoi(token);
|
|
|
|
parmtype = SP_CONSTI;
|
|
|
|
}
|
|
|
|
else if (!Q_stricmp(token, "constf"))
|
|
|
|
{
|
|
|
|
token = Shader_ParseSensString(ptr);
|
|
|
|
specialfloat = atof(token);
|
|
|
|
parmtype = SP_CONSTF;
|
|
|
|
}
|
2006-03-11 03:12:10 +00:00
|
|
|
else if (!Q_stricmp(token, "cvari"))
|
|
|
|
{
|
2010-07-11 02:22:39 +00:00
|
|
|
token = Shader_ParseSensString(ptr);
|
2006-03-11 03:12:10 +00:00
|
|
|
cv = Cvar_Get(token, "", 0, "GLSL Shader parameters");
|
2010-08-28 17:14:38 +00:00
|
|
|
if (!cv)
|
|
|
|
return;
|
2006-03-11 03:12:10 +00:00
|
|
|
parmtype = SP_CVARI;
|
|
|
|
}
|
|
|
|
else if (!Q_stricmp(token, "cvarf"))
|
|
|
|
{
|
2010-07-11 02:22:39 +00:00
|
|
|
token = Shader_ParseSensString(ptr);
|
2006-03-11 03:12:10 +00:00
|
|
|
cv = Cvar_Get(token, "", 0, "GLSL Shader parameters");
|
2010-08-28 17:14:38 +00:00
|
|
|
if (!cv)
|
|
|
|
return;
|
2006-03-11 03:12:10 +00:00
|
|
|
parmtype = SP_CVARF;
|
|
|
|
}
|
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
|
|
|
else if (!Q_stricmp(token, "cvar3f"))
|
|
|
|
{
|
|
|
|
token = Shader_ParseSensString(ptr);
|
|
|
|
cv = Cvar_Get(token, "", 0, "GLSL Shader parameters");
|
2010-08-28 17:14:38 +00:00
|
|
|
if (!cv)
|
|
|
|
return;
|
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
|
|
|
parmtype = SP_CVAR3F;
|
|
|
|
}
|
2006-03-11 03:12:10 +00:00
|
|
|
else if (!Q_stricmp(token, "time"))
|
|
|
|
parmtype = SP_TIME;
|
2008-12-23 02:55:20 +00:00
|
|
|
else if (!Q_stricmp(token, "eyepos"))
|
|
|
|
parmtype = SP_EYEPOS;
|
2009-11-04 21:16:50 +00:00
|
|
|
else if (!Q_stricmp(token, "entmatrix"))
|
|
|
|
parmtype = SP_ENTMATRIX;
|
2008-12-23 02:55:20 +00:00
|
|
|
else if (!Q_stricmp(token, "colours") || !Q_stricmp(token, "colors"))
|
|
|
|
parmtype = SP_ENTCOLOURS;
|
|
|
|
else if (!Q_stricmp(token, "upper"))
|
|
|
|
parmtype = SP_TOPCOLOURS;
|
|
|
|
else if (!Q_stricmp(token, "lower"))
|
|
|
|
parmtype = SP_BOTTOMCOLOURS;
|
2009-07-18 20:46:42 +00:00
|
|
|
else if (!Q_stricmp(token, "lightradius"))
|
|
|
|
parmtype = SP_LIGHTRADIUS;
|
|
|
|
else if (!Q_stricmp(token, "lightcolour"))
|
|
|
|
parmtype = SP_LIGHTCOLOUR;
|
|
|
|
else if (!Q_stricmp(token, "lightpos"))
|
|
|
|
parmtype = SP_LIGHTPOSITION;
|
2010-07-25 15:12:12 +00:00
|
|
|
else if (!Q_stricmp(token, "rendertexturescale"))
|
|
|
|
parmtype = SP_RENDERTEXTURESCALE;
|
2009-07-18 20:46:42 +00:00
|
|
|
else
|
|
|
|
Con_Printf("shader %s: parameter type \"%s\" not known\n", shader->name, token);
|
2006-03-11 03:12:10 +00:00
|
|
|
|
2010-07-11 02:22:39 +00:00
|
|
|
token = Shader_ParseSensString(ptr);
|
2006-03-11 03:12:10 +00:00
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
#ifdef GLQUAKE
|
|
|
|
if (qrenderer == QR_OPENGL)
|
|
|
|
{
|
2010-11-02 23:17:25 +00:00
|
|
|
int p;
|
|
|
|
qboolean foundone;
|
2009-11-04 21:16:50 +00:00
|
|
|
unsigned int uniformloc;
|
2010-08-28 17:14:38 +00:00
|
|
|
if (!shader->programhandle[0].glsl)
|
2006-03-11 03:12:10 +00:00
|
|
|
{
|
2009-11-04 21:16:50 +00:00
|
|
|
Con_Printf("shader %s: param without program set\n", shader->name);
|
2006-03-11 03:12:10 +00:00
|
|
|
}
|
2010-08-28 17:14:38 +00:00
|
|
|
else if (shader->numprogparams == SHADER_PROGPARMS_MAX)
|
|
|
|
Con_Printf("shader %s: too many parms\n", shader->name);
|
2006-03-11 03:12:10 +00:00
|
|
|
else
|
|
|
|
{
|
2010-08-28 17:14:38 +00:00
|
|
|
foundone = false;
|
|
|
|
shader->progparm[shader->numprogparams].type = parmtype;
|
|
|
|
for (p = 0; p < PERMUTATIONS; p++)
|
2009-11-04 21:16:50 +00:00
|
|
|
{
|
2010-08-28 17:14:38 +00:00
|
|
|
if (!shader->programhandle[p].glsl)
|
|
|
|
continue;
|
|
|
|
GLSlang_UseProgram(shader->programhandle[p].glsl);
|
|
|
|
uniformloc = qglGetUniformLocationARB(shader->programhandle[p].glsl, token);
|
|
|
|
shader->progparm[shader->numprogparams].handle[p] = uniformloc;
|
|
|
|
if (uniformloc != -1)
|
2009-11-04 21:16:50 +00:00
|
|
|
{
|
2010-08-28 17:14:38 +00:00
|
|
|
foundone = true;
|
|
|
|
switch(parmtype)
|
|
|
|
{
|
|
|
|
case SP_BAD:
|
|
|
|
foundone = false;
|
|
|
|
break;
|
|
|
|
case SP_TEXTURE:
|
2010-11-10 03:32:47 +00:00
|
|
|
case SP_CONSTI:
|
2010-08-28 17:14:38 +00:00
|
|
|
shader->progparm[shader->numprogparams].ival = specialint;
|
|
|
|
break;
|
2010-11-10 03:32:47 +00:00
|
|
|
case SP_CONSTF:
|
|
|
|
shader->progparm[shader->numprogparams].fval = specialfloat;
|
|
|
|
break;
|
2010-08-28 17:14:38 +00:00
|
|
|
case SP_CVARF:
|
|
|
|
case SP_CVARI:
|
|
|
|
shader->progparm[shader->numprogparams].pval = cv;
|
|
|
|
break;
|
|
|
|
case SP_CVAR3F:
|
|
|
|
shader->progparm[shader->numprogparams].pval = cv;
|
|
|
|
qglUniform3fvARB(uniformloc, 1, specialvec);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2009-11-04 21:16:50 +00:00
|
|
|
}
|
2006-03-11 03:12:10 +00:00
|
|
|
}
|
2010-08-28 17:14:38 +00:00
|
|
|
if (!foundone && !silent)
|
|
|
|
Con_Printf("shader %s: param without uniform \"%s\"\n", shader->name, token);
|
|
|
|
else
|
|
|
|
shader->numprogparams++;
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
GLSlang_UseProgram(0);
|
2006-03-11 03:12:10 +00:00
|
|
|
}
|
|
|
|
}
|
2009-11-04 21:16:50 +00:00
|
|
|
#endif
|
2006-03-11 03:12:10 +00:00
|
|
|
}
|
|
|
|
|
2004-10-19 15:56:22 +00:00
|
|
|
static shaderkey_t shaderkeys[] =
|
|
|
|
{
|
2009-11-04 21:16:50 +00:00
|
|
|
{"cull", Shader_Cull},
|
|
|
|
{"skyparms", Shader_SkyParms},
|
|
|
|
{"fogparms", Shader_FogParms},
|
|
|
|
{"surfaceparm", Shader_SurfaceParm},
|
|
|
|
{"nomipmaps", Shader_NoMipMaps},
|
|
|
|
{"nopicmip", Shader_NoPicMip},
|
|
|
|
{"polygonoffset", Shader_PolygonOffset},
|
|
|
|
{"sort", Shader_Sort},
|
|
|
|
{"deformvertexes", Shader_DeformVertexes},
|
|
|
|
{"portal", Shader_Portal},
|
|
|
|
{"entitymergable", Shader_EntityMergable},
|
|
|
|
|
|
|
|
{"glslprogram", Shader_GLSLProgramName},
|
|
|
|
{"program", Shader_GLSLProgramName}, //legacy
|
|
|
|
{"hlslprogram", Shader_HLSLProgramName}, //for d3d
|
|
|
|
{"param", Shader_ProgramParam},
|
2006-03-11 03:12:10 +00:00
|
|
|
|
2004-10-19 15:56:22 +00:00
|
|
|
{NULL, NULL}
|
|
|
|
};
|
|
|
|
|
|
|
|
// ===============================================================
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
static void Shaderpass_Map (shader_t *shader, shaderpass_t *pass, char **ptr)
|
2004-10-19 15:56:22 +00:00
|
|
|
{
|
|
|
|
int flags;
|
|
|
|
char *token;
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
pass->anim_frames[0] = r_nulltex;
|
|
|
|
|
|
|
|
token = Shader_ParseString (ptr);
|
|
|
|
if (!Q_stricmp (token, "$lightmap"))
|
2005-01-07 03:10:11 +00:00
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
pass->tcgen = TC_GEN_LIGHTMAP;
|
2010-11-02 23:17:25 +00:00
|
|
|
pass->flags |= SHADER_PASS_LIGHTMAP | SHADER_PASS_NOMIPMAP;
|
2009-11-04 21:16:50 +00:00
|
|
|
pass->texgen = T_GEN_LIGHTMAP;
|
|
|
|
shader->flags |= SHADER_HASLIGHTMAP;
|
2005-01-07 03:10:11 +00:00
|
|
|
}
|
2009-11-04 21:16:50 +00:00
|
|
|
else if (!Q_stricmp (token, "$deluxmap"))
|
2005-01-07 03:10:11 +00:00
|
|
|
{
|
|
|
|
pass->tcgen = TC_GEN_LIGHTMAP;
|
2010-11-02 23:17:25 +00:00
|
|
|
pass->flags |= SHADER_PASS_DELUXMAP | SHADER_PASS_NOMIPMAP;
|
2009-11-04 21:16:50 +00:00
|
|
|
pass->texgen = T_GEN_DELUXMAP;
|
|
|
|
}
|
|
|
|
else if (!Q_stricmp (token, "$diffuse"))
|
|
|
|
{
|
|
|
|
pass->texgen = T_GEN_DIFFUSE;
|
|
|
|
pass->tcgen = TC_GEN_BASE;
|
|
|
|
}
|
|
|
|
else if (!Q_stricmp (token, "$normalmap"))
|
|
|
|
{
|
|
|
|
pass->texgen = T_GEN_NORMALMAP;
|
|
|
|
pass->tcgen = TC_GEN_BASE;
|
|
|
|
}
|
|
|
|
else if (!Q_stricmp (token, "$specular"))
|
|
|
|
{
|
|
|
|
pass->texgen = T_GEN_SPECULAR;
|
|
|
|
pass->tcgen = TC_GEN_BASE;
|
|
|
|
}
|
|
|
|
else if (!Q_stricmp (token, "$fullbright"))
|
|
|
|
{
|
|
|
|
pass->texgen = T_GEN_FULLBRIGHT;
|
|
|
|
pass->tcgen = TC_GEN_BASE;
|
|
|
|
}
|
|
|
|
else if (!Q_stricmp (token, "$upperoverlay"))
|
|
|
|
{
|
2010-07-18 12:52:24 +00:00
|
|
|
shader->flags |= SHADER_HASTOPBOTTOM;
|
2009-11-04 21:16:50 +00:00
|
|
|
pass->texgen = T_GEN_UPPEROVERLAY;
|
|
|
|
pass->tcgen = TC_GEN_BASE;
|
|
|
|
}
|
|
|
|
else if (!Q_stricmp (token, "$loweroverlay"))
|
|
|
|
{
|
2010-07-18 12:52:24 +00:00
|
|
|
shader->flags |= SHADER_HASTOPBOTTOM;
|
2009-11-04 21:16:50 +00:00
|
|
|
pass->texgen = T_GEN_LOWEROVERLAY;
|
|
|
|
pass->tcgen = TC_GEN_BASE;
|
|
|
|
}
|
|
|
|
else if (!Q_stricmp (token, "$shadowmap"))
|
|
|
|
{
|
|
|
|
pass->texgen = T_GEN_SHADOWMAP;
|
|
|
|
pass->tcgen = TC_GEN_BASE; //FIXME: moo!
|
|
|
|
}
|
|
|
|
else if (!Q_stricmp (token, "$currentrender"))
|
|
|
|
{
|
|
|
|
pass->texgen = T_GEN_CURRENTRENDER;
|
|
|
|
pass->tcgen = TC_GEN_BASE; //FIXME: moo!
|
2005-01-07 03:10:11 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-11-04 21:16:50 +00:00
|
|
|
flags = Shader_SetImageFlags (shader);
|
2004-10-19 15:56:22 +00:00
|
|
|
|
|
|
|
pass->tcgen = TC_GEN_BASE;
|
2009-11-04 21:16:50 +00:00
|
|
|
pass->anim_frames[0] = Shader_FindImage (token, flags);
|
2004-10-19 15:56:22 +00:00
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
/*
|
|
|
|
if (!pass->anim_frames[0])
|
|
|
|
{
|
2006-03-06 01:41:09 +00:00
|
|
|
pass->anim_frames[0] = missing_texture;
|
2007-09-23 15:28:06 +00:00
|
|
|
Con_DPrintf (CON_WARNING "Shader %s has a stage with no image: %s.\n", shader->name, token );
|
2004-10-19 15:56:22 +00:00
|
|
|
}
|
2009-11-04 21:16:50 +00:00
|
|
|
*/
|
2004-10-19 15:56:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
static void Shaderpass_AnimMap (shader_t *shader, shaderpass_t *pass, char **ptr)
|
2004-10-19 15:56:22 +00:00
|
|
|
{
|
|
|
|
int flags;
|
|
|
|
char *token;
|
2009-11-04 21:16:50 +00:00
|
|
|
texid_t image;
|
2004-10-19 15:56:22 +00:00
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
flags = Shader_SetImageFlags (shader);
|
2004-10-19 15:56:22 +00:00
|
|
|
|
|
|
|
pass->tcgen = TC_GEN_BASE;
|
|
|
|
pass->flags |= SHADER_PASS_ANIMMAP;
|
2009-11-04 21:16:50 +00:00
|
|
|
pass->texgen = T_GEN_ANIMMAP;
|
|
|
|
pass->anim_fps = (int)Shader_ParseFloat (ptr);
|
2004-10-19 15:56:22 +00:00
|
|
|
pass->anim_numframes = 0;
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
for ( ; ; )
|
|
|
|
{
|
|
|
|
token = Shader_ParseString(ptr);
|
|
|
|
if (!token[0])
|
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
if (pass->anim_numframes < SHADER_ANIM_FRAMES_MAX)
|
|
|
|
{
|
|
|
|
image = Shader_FindImage (token, flags);
|
2004-10-19 15:56:22 +00:00
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
if (!TEXVALID(image))
|
|
|
|
{
|
2006-03-06 01:41:09 +00:00
|
|
|
pass->anim_frames[pass->anim_numframes++] = missing_texture;
|
2007-09-23 15:28:06 +00:00
|
|
|
Con_DPrintf (CON_WARNING "Shader %s has an animmap with no image: %s.\n", shader->name, token );
|
2009-11-04 21:16:50 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
pass->anim_frames[pass->anim_numframes++] = image;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
static void Shaderpass_ClampMap (shader_t *shader, shaderpass_t *pass, char **ptr)
|
2004-10-19 15:56:22 +00:00
|
|
|
{
|
|
|
|
int flags;
|
|
|
|
char *token;
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
token = Shader_ParseString (ptr);
|
|
|
|
flags = Shader_SetImageFlags (shader);
|
2004-10-19 15:56:22 +00:00
|
|
|
|
|
|
|
pass->tcgen = TC_GEN_BASE;
|
2009-11-04 21:16:50 +00:00
|
|
|
pass->anim_frames[0] = Shader_FindImage (token, flags | IF_CLAMP);
|
|
|
|
pass->texgen = T_GEN_SINGLEMAP;
|
2010-11-11 18:22:49 +00:00
|
|
|
pass->flags |= SHADER_PASS_CLAMP;
|
2004-10-19 15:56:22 +00:00
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
if (!TEXVALID(pass->anim_frames[0]))
|
|
|
|
{
|
2006-03-06 01:41:09 +00:00
|
|
|
pass->anim_frames[0] = missing_texture;
|
2009-11-04 21:16:50 +00:00
|
|
|
Con_DPrintf (CON_WARNING "Shader %s has a stage with no image: %s.\n", shader->name, token);
|
2004-10-19 15:56:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
static void Shaderpass_VideoMap (shader_t *shader, shaderpass_t *pass, char **ptr)
|
2004-10-19 15:56:22 +00:00
|
|
|
{
|
2006-03-06 01:41:09 +00:00
|
|
|
char *token;
|
2004-10-19 15:56:22 +00:00
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
token = Shader_ParseString (ptr);
|
2004-10-19 15:56:22 +00:00
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
#ifdef NOMEDIA
|
|
|
|
#else
|
|
|
|
if (pass->cin)
|
|
|
|
Z_Free (pass->cin);
|
2004-10-19 15:56:22 +00:00
|
|
|
|
2006-03-06 01:41:09 +00:00
|
|
|
pass->cin = Media_StartCin(token);
|
|
|
|
if (!pass->cin)
|
|
|
|
pass->cin = Media_StartCin(va("video/%s.roq", token));
|
|
|
|
else
|
2009-11-04 21:16:50 +00:00
|
|
|
Con_DPrintf (CON_WARNING "(shader %s) Couldn't load video %s\n", shader->name, token);
|
2006-03-06 01:41:09 +00:00
|
|
|
|
2010-05-01 22:47:47 +00:00
|
|
|
if (pass->cin)
|
|
|
|
{
|
|
|
|
pass->flags |= SHADER_PASS_VIDEOMAP;
|
|
|
|
shader->flags |= SHADER_VIDEOMAP;
|
|
|
|
pass->texgen = T_GEN_VIDEOMAP;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pass->texgen = T_GEN_DIFFUSE;
|
|
|
|
pass->rgbgen = RGB_GEN_CONST;
|
|
|
|
pass->rgbgen_func.type = SHADER_FUNC_CONSTANT;
|
|
|
|
pass->rgbgen_func.args[0] = pass->rgbgen_func.args[1] = pass->rgbgen_func.args[2] = 0;
|
|
|
|
}
|
2009-11-04 21:16:50 +00:00
|
|
|
#endif
|
2004-10-19 15:56:22 +00:00
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
static void Shaderpass_RGBGen (shader_t *shader, shaderpass_t *pass, char **ptr)
|
2004-10-19 15:56:22 +00:00
|
|
|
{
|
|
|
|
char *token;
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
token = Shader_ParseString (ptr);
|
|
|
|
if (!Q_stricmp (token, "identitylighting"))
|
2004-10-19 15:56:22 +00:00
|
|
|
pass->rgbgen = RGB_GEN_IDENTITY_LIGHTING;
|
2009-11-04 21:16:50 +00:00
|
|
|
else if (!Q_stricmp (token, "identity"))
|
2004-10-19 15:56:22 +00:00
|
|
|
pass->rgbgen = RGB_GEN_IDENTITY;
|
2009-11-04 21:16:50 +00:00
|
|
|
else if (!Q_stricmp (token, "wave"))
|
2005-02-06 02:47:36 +00:00
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
pass->rgbgen = RGB_GEN_WAVE;
|
2009-11-04 21:16:50 +00:00
|
|
|
Shader_ParseFunc ( ptr, &pass->rgbgen_func);
|
2005-02-06 02:47:36 +00:00
|
|
|
}
|
2009-11-04 21:16:50 +00:00
|
|
|
else if (!Q_stricmp(token, "entity"))
|
2004-10-19 15:56:22 +00:00
|
|
|
pass->rgbgen = RGB_GEN_ENTITY;
|
2009-11-04 21:16:50 +00:00
|
|
|
else if (!Q_stricmp (token, "oneMinusEntity"))
|
2004-10-19 15:56:22 +00:00
|
|
|
pass->rgbgen = RGB_GEN_ONE_MINUS_ENTITY;
|
2009-11-04 21:16:50 +00:00
|
|
|
else if (!Q_stricmp (token, "vertex"))
|
2004-10-19 15:56:22 +00:00
|
|
|
pass->rgbgen = RGB_GEN_VERTEX;
|
2009-11-04 21:16:50 +00:00
|
|
|
else if (!Q_stricmp (token, "oneMinusVertex"))
|
2004-10-19 15:56:22 +00:00
|
|
|
pass->rgbgen = RGB_GEN_ONE_MINUS_VERTEX;
|
2009-11-04 21:16:50 +00:00
|
|
|
else if (!Q_stricmp (token, "lightingDiffuse"))
|
2004-10-19 15:56:22 +00:00
|
|
|
pass->rgbgen = RGB_GEN_LIGHTING_DIFFUSE;
|
2009-11-04 21:16:50 +00:00
|
|
|
else if (!Q_stricmp (token, "exactvertex"))
|
2004-10-19 15:56:22 +00:00
|
|
|
pass->rgbgen = RGB_GEN_EXACT_VERTEX;
|
2009-11-04 21:16:50 +00:00
|
|
|
else if (!Q_stricmp (token, "const") || !Q_stricmp (token, "constant"))
|
2005-02-06 02:47:36 +00:00
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
pass->rgbgen = RGB_GEN_CONST;
|
|
|
|
pass->rgbgen_func.type = SHADER_FUNC_CONSTANT;
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
Shader_ParseVector (ptr, pass->rgbgen_func.args);
|
2004-10-19 15:56:22 +00:00
|
|
|
}
|
2009-11-04 21:16:50 +00:00
|
|
|
else if (!Q_stricmp (token, "topcolor"))
|
2005-02-06 02:47:36 +00:00
|
|
|
pass->rgbgen = RGB_GEN_TOPCOLOR;
|
2009-11-04 21:16:50 +00:00
|
|
|
else if (!Q_stricmp (token, "bottomcolor"))
|
2005-02-06 02:47:36 +00:00
|
|
|
pass->rgbgen = RGB_GEN_BOTTOMCOLOR;
|
2004-10-19 15:56:22 +00:00
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
static void Shaderpass_AlphaGen (shader_t *shader, shaderpass_t *pass, char **ptr)
|
2004-10-19 15:56:22 +00:00
|
|
|
{
|
|
|
|
char *token;
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
token = Shader_ParseString(ptr);
|
|
|
|
if (!Q_stricmp (token, "portal"))
|
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
pass->alphagen = ALPHA_GEN_PORTAL;
|
2010-07-11 02:22:39 +00:00
|
|
|
shader->portaldist = Shader_ParseFloat(ptr);
|
|
|
|
if (!shader->portaldist)
|
|
|
|
shader->portaldist = 256;
|
2004-10-19 15:56:22 +00:00
|
|
|
shader->flags |= SHADER_AGEN_PORTAL;
|
2009-11-04 21:16:50 +00:00
|
|
|
}
|
|
|
|
else if (!Q_stricmp (token, "vertex"))
|
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
pass->alphagen = ALPHA_GEN_VERTEX;
|
2009-11-04 21:16:50 +00:00
|
|
|
}
|
|
|
|
else if (!Q_stricmp (token, "entity"))
|
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
pass->alphagen = ALPHA_GEN_ENTITY;
|
2009-11-04 21:16:50 +00:00
|
|
|
}
|
|
|
|
else if (!Q_stricmp (token, "wave"))
|
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
pass->alphagen = ALPHA_GEN_WAVE;
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
Shader_ParseFunc (ptr, &pass->alphagen_func);
|
|
|
|
}
|
|
|
|
else if ( !Q_stricmp (token, "lightingspecular"))
|
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
pass->alphagen = ALPHA_GEN_SPECULAR;
|
2009-11-04 21:16:50 +00:00
|
|
|
}
|
|
|
|
else if ( !Q_stricmp (token, "const") || !Q_stricmp (token, "constant"))
|
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
pass->alphagen = ALPHA_GEN_CONST;
|
|
|
|
pass->alphagen_func.type = SHADER_FUNC_CONSTANT;
|
2009-11-04 21:16:50 +00:00
|
|
|
pass->alphagen_func.args[0] = fabs(Shader_ParseFloat(ptr));
|
2004-10-19 15:56:22 +00:00
|
|
|
}
|
|
|
|
}
|
2009-11-04 21:16:50 +00:00
|
|
|
static void Shaderpass_AlphaShift (shader_t *shader, shaderpass_t *pass, char **ptr) //for alienarena
|
2006-02-27 00:42:25 +00:00
|
|
|
{
|
|
|
|
float speed;
|
|
|
|
float min, max;
|
|
|
|
pass->alphagen = ALPHA_GEN_WAVE;
|
|
|
|
|
|
|
|
pass->alphagen_func.type = SHADER_FUNC_SIN;
|
|
|
|
|
|
|
|
|
|
|
|
//arg0 = add
|
|
|
|
//arg1 = scale
|
|
|
|
//arg2 = timeshift
|
|
|
|
//arg3 = timescale
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
speed = Shader_ParseFloat(ptr);
|
|
|
|
min = Shader_ParseFloat(ptr);
|
|
|
|
max = Shader_ParseFloat(ptr);
|
2006-02-27 00:42:25 +00:00
|
|
|
|
|
|
|
pass->alphagen_func.args[0] = min + (max - min)/2;
|
|
|
|
pass->alphagen_func.args[1] = (max - min)/2;
|
|
|
|
pass->alphagen_func.args[2] = 0;
|
|
|
|
pass->alphagen_func.args[3] = 1/speed;
|
|
|
|
}
|
2004-10-19 15:56:22 +00:00
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
static int Shader_BlendFactor(char *name, qboolean dstnotsrc)
|
|
|
|
{
|
|
|
|
int factor;
|
|
|
|
if (!strnicmp(name, "gl_", 3))
|
|
|
|
name += 3;
|
|
|
|
|
|
|
|
if (!Q_stricmp(name, "zero"))
|
|
|
|
factor = SBITS_SRCBLEND_ZERO;
|
|
|
|
else if ( !Q_stricmp(name, "one"))
|
|
|
|
factor = SBITS_SRCBLEND_ONE;
|
|
|
|
else if (!Q_stricmp(name, "dst_color"))
|
|
|
|
factor = SBITS_SRCBLEND_DST_COLOR;
|
|
|
|
else if (!Q_stricmp(name, "one_minus_src_alpha"))
|
|
|
|
factor = SBITS_SRCBLEND_ONE_MINUS_SRC_ALPHA;
|
|
|
|
else if (!Q_stricmp(name, "src_alpha"))
|
|
|
|
factor = SBITS_SRCBLEND_SRC_ALPHA;
|
|
|
|
else if (!Q_stricmp(name, "src_color"))
|
|
|
|
factor = SBITS_SRCBLEND_SRC_COLOR_INVALID;
|
|
|
|
else if (!Q_stricmp(name, "one_minus_dst_color"))
|
|
|
|
factor = SBITS_SRCBLEND_ONE_MINUS_DST_COLOR;
|
|
|
|
else if (!Q_stricmp(name, "one_minus_src_color"))
|
|
|
|
factor = SBITS_SRCBLEND_ONE_MINUS_SRC_COLOR_INVALID;
|
|
|
|
else if (!Q_stricmp(name, "dst_alpha") )
|
|
|
|
factor = SBITS_SRCBLEND_DST_ALPHA;
|
|
|
|
else if (!Q_stricmp(name, "one_minus_dst_alpha"))
|
|
|
|
factor = SBITS_SRCBLEND_ONE_MINUS_DST_ALPHA;
|
|
|
|
else
|
|
|
|
factor = SBITS_SRCBLEND_NONE;
|
|
|
|
|
|
|
|
if (dstnotsrc)
|
|
|
|
{
|
|
|
|
//dest factors are shifted
|
|
|
|
factor <<= 4;
|
|
|
|
|
|
|
|
/*gl doesn't accept dst_color for destinations*/
|
|
|
|
if (factor == SBITS_DSTBLEND_NONE ||
|
|
|
|
factor == SBITS_DSTBLEND_DST_COLOR_INVALID ||
|
|
|
|
factor == SBITS_DSTBLEND_ONE_MINUS_DST_COLOR_INVALID ||
|
|
|
|
factor == SBITS_DSTBLEND_ALPHA_SATURATE_INVALID)
|
|
|
|
{
|
|
|
|
Con_DPrintf("Invalid shader dst blend \"%s\"\n", name);
|
|
|
|
factor = SBITS_DSTBLEND_ONE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/*gl doesn't accept src_color for sources*/
|
|
|
|
if (factor == SBITS_SRCBLEND_NONE ||
|
|
|
|
factor == SBITS_SRCBLEND_SRC_COLOR_INVALID ||
|
|
|
|
factor == SBITS_SRCBLEND_ONE_MINUS_SRC_COLOR_INVALID)
|
|
|
|
{
|
|
|
|
Con_DPrintf("Unrecognised shader src blend \"%s\"\n", name);
|
|
|
|
factor = SBITS_SRCBLEND_ONE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return factor;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void Shaderpass_BlendFunc (shader_t *shader, shaderpass_t *pass, char **ptr)
|
2004-10-19 15:56:22 +00:00
|
|
|
{
|
|
|
|
char *token;
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
pass->shaderbits &= ~(SBITS_BLEND_BITS);
|
2004-10-19 15:56:22 +00:00
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
token = Shader_ParseString (ptr);
|
|
|
|
if ( !Q_stricmp (token, "blend"))
|
|
|
|
{
|
|
|
|
pass->shaderbits |= SBITS_SRCBLEND_SRC_ALPHA | SBITS_DSTBLEND_ONE_MINUS_SRC_ALPHA;
|
|
|
|
}
|
|
|
|
else if (!Q_stricmp (token, "filter"))
|
|
|
|
{
|
|
|
|
pass->shaderbits |= SBITS_SRCBLEND_DST_COLOR | SBITS_DSTBLEND_ZERO;
|
|
|
|
}
|
|
|
|
else if (!Q_stricmp (token, "add"))
|
|
|
|
{
|
2010-11-07 02:53:46 +00:00
|
|
|
pass->shaderbits |= SBITS_SRCBLEND_ONE | SBITS_DSTBLEND_ONE;
|
2009-11-04 21:16:50 +00:00
|
|
|
}
|
|
|
|
else if (!Q_stricmp (token, "replace"))
|
|
|
|
{
|
|
|
|
pass->shaderbits |= SBITS_SRCBLEND_NONE | SBITS_DSTBLEND_NONE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pass->shaderbits |= Shader_BlendFactor(token, false);
|
2004-10-19 15:56:22 +00:00
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
token = Shader_ParseString (ptr);
|
|
|
|
pass->shaderbits |= Shader_BlendFactor(token, true);
|
2004-10-19 15:56:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
static void Shaderpass_AlphaFunc (shader_t *shader, shaderpass_t *pass, char **ptr)
|
2004-10-19 15:56:22 +00:00
|
|
|
{
|
|
|
|
char *token;
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
pass->shaderbits &= ~SBITS_ATEST_BITS;
|
2004-10-19 15:56:22 +00:00
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
token = Shader_ParseString (ptr);
|
|
|
|
if (!Q_stricmp (token, "gt0"))
|
|
|
|
{
|
|
|
|
pass->shaderbits = SBITS_ATEST_GT0;
|
|
|
|
}
|
|
|
|
else if (!Q_stricmp (token, "lt128"))
|
|
|
|
{
|
|
|
|
pass->shaderbits = SBITS_ATEST_LT128;
|
|
|
|
}
|
|
|
|
else if (!Q_stricmp (token, "ge128"))
|
|
|
|
{
|
|
|
|
pass->shaderbits = SBITS_ATEST_GE128;
|
|
|
|
}
|
2004-10-19 15:56:22 +00:00
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
static void Shaderpass_DepthFunc (shader_t *shader, shaderpass_t *pass, char **ptr)
|
2004-10-19 15:56:22 +00:00
|
|
|
{
|
|
|
|
char *token;
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
token = Shader_ParseString (ptr);
|
|
|
|
if (!Q_stricmp (token, "equal"))
|
|
|
|
pass->shaderbits |= SBITS_MISC_DEPTHEQUALONLY;
|
|
|
|
else if (!Q_stricmp (token, "lequal"))
|
|
|
|
pass->shaderbits &= ~SBITS_MISC_DEPTHEQUALONLY;
|
|
|
|
else
|
|
|
|
Con_DPrintf("Invalid depth func %s\n", token);
|
2004-10-19 15:56:22 +00:00
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
static void Shaderpass_DepthWrite (shader_t *shader, shaderpass_t *pass, char **ptr)
|
2004-10-19 15:56:22 +00:00
|
|
|
{
|
|
|
|
shader->flags |= SHADER_DEPTHWRITE;
|
2009-11-04 21:16:50 +00:00
|
|
|
pass->shaderbits |= SBITS_MISC_DEPTHWRITE;
|
2004-10-19 15:56:22 +00:00
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
static void Shaderpass_TcMod (shader_t *shader, shaderpass_t *pass, char **ptr)
|
2004-10-19 15:56:22 +00:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
tcmod_t *tcmod;
|
|
|
|
char *token;
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
if (pass->numtcmods >= SHADER_TCMOD_MAX)
|
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
tcmod = &pass->tcmods[pass->numtcmods];
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
token = Shader_ParseString (ptr);
|
|
|
|
if (!Q_stricmp (token, "rotate"))
|
|
|
|
{
|
|
|
|
tcmod->args[0] = -Shader_ParseFloat(ptr) / 360.0f;
|
|
|
|
if (!tcmod->args[0])
|
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
tcmod->type = SHADER_TCMOD_ROTATE;
|
2009-11-04 21:16:50 +00:00
|
|
|
}
|
|
|
|
else if ( !Q_stricmp (token, "scale") )
|
|
|
|
{
|
|
|
|
tcmod->args[0] = Shader_ParseFloat (ptr);
|
|
|
|
tcmod->args[1] = Shader_ParseFloat (ptr);
|
2004-10-19 15:56:22 +00:00
|
|
|
tcmod->type = SHADER_TCMOD_SCALE;
|
2009-11-04 21:16:50 +00:00
|
|
|
}
|
|
|
|
else if ( !Q_stricmp (token, "scroll") )
|
|
|
|
{
|
|
|
|
tcmod->args[0] = Shader_ParseFloat (ptr);
|
|
|
|
tcmod->args[1] = Shader_ParseFloat (ptr);
|
2004-10-19 15:56:22 +00:00
|
|
|
tcmod->type = SHADER_TCMOD_SCROLL;
|
2009-11-04 21:16:50 +00:00
|
|
|
}
|
|
|
|
else if (!Q_stricmp(token, "stretch"))
|
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
shaderfunc_t func;
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
Shader_ParseFunc(ptr, &func);
|
2004-10-19 15:56:22 +00:00
|
|
|
|
|
|
|
tcmod->args[0] = func.type;
|
|
|
|
for (i = 1; i < 5; ++i)
|
|
|
|
tcmod->args[i] = func.args[i-1];
|
|
|
|
tcmod->type = SHADER_TCMOD_STRETCH;
|
2009-11-04 21:16:50 +00:00
|
|
|
}
|
|
|
|
else if (!Q_stricmp (token, "transform"))
|
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
for (i = 0; i < 6; ++i)
|
2009-11-04 21:16:50 +00:00
|
|
|
tcmod->args[i] = Shader_ParseFloat (ptr);
|
2004-10-19 15:56:22 +00:00
|
|
|
tcmod->type = SHADER_TCMOD_TRANSFORM;
|
2009-11-04 21:16:50 +00:00
|
|
|
}
|
|
|
|
else if (!Q_stricmp (token, "turb"))
|
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
for (i = 0; i < 4; i++)
|
2009-11-04 21:16:50 +00:00
|
|
|
tcmod->args[i] = Shader_ParseFloat (ptr);
|
2004-10-19 15:56:22 +00:00
|
|
|
tcmod->type = SHADER_TCMOD_TURB;
|
2009-11-04 21:16:50 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
pass->numtcmods++;
|
|
|
|
}
|
|
|
|
|
2006-02-27 00:42:25 +00:00
|
|
|
static void Shaderpass_Scale ( shader_t *shader, shaderpass_t *pass, char **ptr )
|
|
|
|
{
|
|
|
|
//seperate x and y
|
|
|
|
char *token;
|
|
|
|
tcmod_t *tcmod;
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
pass->numtcmods++;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void Shaderpass_Scroll ( shader_t *shader, shaderpass_t *pass, char **ptr )
|
|
|
|
{
|
|
|
|
//seperate x and y
|
|
|
|
char *token;
|
|
|
|
tcmod_t *tcmod;
|
|
|
|
|
|
|
|
tcmod = &pass->tcmods[pass->numtcmods];
|
|
|
|
|
|
|
|
token = Shader_ParseString ( ptr );
|
|
|
|
if (!strcmp(token, "static"))
|
|
|
|
{
|
|
|
|
tcmod->type = SHADER_TCMOD_SCROLL;
|
|
|
|
tcmod->args[0] = Shader_ParseFloat ( ptr );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Con_Printf("Bad shader scale\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
token = Shader_ParseString ( ptr );
|
|
|
|
if (!strcmp(token, "static"))
|
|
|
|
{
|
|
|
|
tcmod->type = SHADER_TCMOD_SCROLL;
|
|
|
|
tcmod->args[1] = Shader_ParseFloat ( ptr );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Con_Printf("Bad shader scale\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
pass->numtcmods++;
|
|
|
|
}
|
|
|
|
|
2004-10-19 15:56:22 +00:00
|
|
|
|
|
|
|
static void Shaderpass_TcGen ( shader_t *shader, shaderpass_t *pass, char **ptr )
|
|
|
|
{
|
|
|
|
char *token;
|
|
|
|
|
|
|
|
token = Shader_ParseString ( ptr );
|
|
|
|
if ( !Q_stricmp (token, "base") ) {
|
|
|
|
pass->tcgen = TC_GEN_BASE;
|
|
|
|
} else if ( !Q_stricmp (token, "lightmap") ) {
|
|
|
|
pass->tcgen = TC_GEN_LIGHTMAP;
|
|
|
|
} else if ( !Q_stricmp (token, "environment") ) {
|
|
|
|
pass->tcgen = TC_GEN_ENVIRONMENT;
|
|
|
|
} else if ( !Q_stricmp (token, "vector") ) {
|
|
|
|
pass->tcgen = TC_GEN_BASE;
|
2009-07-05 18:45:53 +00:00
|
|
|
} else if ( !Q_stricmp (token, "normal") ) {
|
|
|
|
pass->tcgen = TC_GEN_NORMAL;
|
|
|
|
} else if ( !Q_stricmp (token, "svector") ) {
|
|
|
|
pass->tcgen = TC_GEN_SVECTOR;
|
|
|
|
} else if ( !Q_stricmp (token, "tvector") ) {
|
|
|
|
pass->tcgen = TC_GEN_TVECTOR;
|
2004-10-19 15:56:22 +00:00
|
|
|
}
|
|
|
|
}
|
2006-02-27 00:42:25 +00:00
|
|
|
static void Shaderpass_EnvMap ( shader_t *shader, shaderpass_t *pass, char **ptr ) //for alienarena
|
|
|
|
{
|
|
|
|
pass->tcgen = TC_GEN_ENVIRONMENT;
|
|
|
|
}
|
2004-10-19 15:56:22 +00:00
|
|
|
|
|
|
|
static void Shaderpass_Detail ( shader_t *shader, shaderpass_t *pass, char **ptr )
|
|
|
|
{
|
|
|
|
pass->flags |= SHADER_PASS_DETAIL;
|
|
|
|
}
|
|
|
|
|
2006-02-27 00:42:25 +00:00
|
|
|
static void Shaderpass_AlphaMask ( shader_t *shader, shaderpass_t *pass, char **ptr )
|
|
|
|
{
|
2009-11-04 21:16:50 +00:00
|
|
|
pass->shaderbits &= ~SBITS_ATEST_BITS;
|
|
|
|
pass->shaderbits |= SBITS_ATEST_GE128;
|
2006-02-27 00:42:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void Shaderpass_NoLightMap ( shader_t *shader, shaderpass_t *pass, char **ptr )
|
|
|
|
{
|
|
|
|
pass->rgbgen = RGB_GEN_IDENTITY;
|
|
|
|
}
|
|
|
|
|
2004-10-19 15:56:22 +00:00
|
|
|
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 },
|
2006-02-27 00:42:25 +00:00
|
|
|
{"envmap", Shaderpass_EnvMap },//for alienarena
|
|
|
|
{"nolightmap", Shaderpass_NoLightMap },//for alienarena
|
|
|
|
{"scale", Shaderpass_Scale },//for alienarena
|
|
|
|
{"scroll", Shaderpass_Scroll },//for alienarena
|
2004-10-19 15:56:22 +00:00
|
|
|
{"alphagen", Shaderpass_AlphaGen },
|
2006-02-27 00:42:25 +00:00
|
|
|
{"alphashift", Shaderpass_AlphaShift },//for alienarena
|
|
|
|
{"alphamask", Shaderpass_AlphaMask },//for alienarena
|
2004-10-19 15:56:22 +00:00
|
|
|
{"detail", Shaderpass_Detail },
|
|
|
|
{NULL, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
// ===============================================================
|
|
|
|
|
2009-04-01 22:03:56 +00:00
|
|
|
int Shader_InitCallback (const char *name, int size, void *param)
|
2004-10-19 15:56:22 +00:00
|
|
|
{
|
2005-03-28 00:11:59 +00:00
|
|
|
strcpy(shaderbuf+shaderbuflen, name);
|
|
|
|
Shader_MakeCache(shaderbuf+shaderbuflen);
|
|
|
|
shaderbuflen += strlen(name)+1;
|
2004-10-19 15:56:22 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
qboolean Shader_Init (void)
|
|
|
|
{
|
2005-03-28 00:11:59 +00:00
|
|
|
shaderbuflen = 0;
|
|
|
|
|
2010-05-01 22:47:47 +00:00
|
|
|
r_shaders = calloc(MAX_SHADERS, sizeof(shader_t));
|
|
|
|
|
|
|
|
shader_hash = calloc (HASH_SIZE, sizeof(*shader_hash));
|
|
|
|
|
2010-07-11 02:22:39 +00:00
|
|
|
shader_active_hash_mem = malloc(Hash_BytesForBuckets(1024));
|
|
|
|
memset(shader_active_hash_mem, 0, Hash_BytesForBuckets(1024));
|
|
|
|
Hash_InitTable(&shader_active_hash, 1024, shader_active_hash_mem);
|
2004-10-19 15:56:22 +00:00
|
|
|
|
2010-07-11 02:22:39 +00:00
|
|
|
shader_rescan_needed = true;
|
2009-11-04 21:16:50 +00:00
|
|
|
Shader_NeedReload();
|
2010-03-14 14:35:56 +00:00
|
|
|
Shader_DoReload();
|
2004-10-19 15:56:22 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void Shader_MakeCache ( char *path )
|
|
|
|
{
|
|
|
|
unsigned int key, i;
|
|
|
|
char filename[MAX_QPATH];
|
|
|
|
char *buf, *ptr, *token, *t;
|
|
|
|
shadercache_t *cache;
|
|
|
|
int size;
|
|
|
|
|
2005-04-26 16:04:12 +00:00
|
|
|
Com_sprintf( filename, sizeof(filename), "%s", path );
|
2005-01-18 21:06:46 +00:00
|
|
|
Con_DPrintf ( "...loading '%s'\n", filename );
|
2004-10-19 15:56:22 +00:00
|
|
|
|
|
|
|
size = FS_LoadFile ( filename, (void **)&buf );
|
2009-11-04 21:16:50 +00:00
|
|
|
if ( !buf || size <= 0 )
|
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
ptr = buf;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
if ( ptr - buf >= size )
|
|
|
|
break;
|
|
|
|
|
|
|
|
token = COM_ParseExt ( &ptr, true );
|
|
|
|
if ( !token[0] || ptr - buf >= size )
|
|
|
|
break;
|
|
|
|
|
2005-08-26 22:56:51 +00:00
|
|
|
COM_CleanUpPath(token);
|
|
|
|
|
2004-10-19 15:56:22 +00:00
|
|
|
t = NULL;
|
|
|
|
Shader_GetPathAndOffset ( token, &t, &i );
|
2010-07-11 02:22:39 +00:00
|
|
|
if (t)
|
2009-11-04 21:16:50 +00:00
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
ptr = Shader_Skip ( ptr );
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
key = Hash_Key ( token, HASH_SIZE );
|
|
|
|
|
|
|
|
cache = ( shadercache_t * )Z_Malloc ( sizeof(shadercache_t) );
|
|
|
|
cache->hash_next = shader_hash[key];
|
|
|
|
cache->path = path;
|
|
|
|
cache->offset = ptr - buf;
|
|
|
|
Com_sprintf ( cache->name, MAX_QPATH, token );
|
|
|
|
shader_hash[key] = cache;
|
|
|
|
|
|
|
|
ptr = Shader_Skip ( ptr );
|
|
|
|
} while ( ptr );
|
|
|
|
|
|
|
|
FS_FreeFile ( buf );
|
|
|
|
}
|
|
|
|
|
|
|
|
char *Shader_Skip ( char *ptr )
|
|
|
|
{
|
|
|
|
char *tok;
|
|
|
|
int brace_count;
|
|
|
|
|
|
|
|
// Opening brace
|
|
|
|
tok = COM_ParseExt ( &ptr, true );
|
|
|
|
|
|
|
|
if (!ptr)
|
|
|
|
return NULL;
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
if ( tok[0] != '{' )
|
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
tok = COM_ParseExt ( &ptr, true );
|
|
|
|
}
|
|
|
|
|
|
|
|
for (brace_count = 1; brace_count > 0 ; ptr++)
|
|
|
|
{
|
|
|
|
tok = COM_ParseExt ( &ptr, true );
|
|
|
|
|
|
|
|
if ( !tok[0] )
|
|
|
|
return NULL;
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
if (tok[0] == '{')
|
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
brace_count++;
|
2009-11-04 21:16:50 +00:00
|
|
|
} else if (tok[0] == '}')
|
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
brace_count--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void Shader_GetPathAndOffset ( char *name, char **path, unsigned int *offset )
|
|
|
|
{
|
|
|
|
unsigned int key;
|
|
|
|
shadercache_t *cache;
|
|
|
|
|
|
|
|
key = Hash_Key ( name, HASH_SIZE );
|
|
|
|
cache = shader_hash[key];
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
for ( ; cache; cache = cache->hash_next )
|
|
|
|
{
|
|
|
|
if ( !Q_stricmp (cache->name, name) )
|
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
*path = cache->path;
|
|
|
|
*offset = cache->offset;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
path = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Shader_FreePass (shaderpass_t *pass)
|
|
|
|
{
|
2009-11-04 21:16:50 +00:00
|
|
|
#ifndef NOMEDIA
|
2006-03-06 01:41:09 +00:00
|
|
|
if ( pass->flags & SHADER_PASS_VIDEOMAP )
|
|
|
|
{
|
|
|
|
Media_ShutdownCin(pass->cin);
|
2004-10-19 15:56:22 +00:00
|
|
|
pass->cin = NULL;
|
2006-03-06 01:41:09 +00:00
|
|
|
}
|
2009-11-04 21:16:50 +00:00
|
|
|
#endif
|
2004-10-19 15:56:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Shader_Free (shader_t *shader)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
shaderpass_t *pass;
|
|
|
|
|
2010-07-18 08:42:59 +00:00
|
|
|
if (shader->bucket.data == shader)
|
|
|
|
Hash_RemoveData(&shader_active_hash, shader->name, shader);
|
2010-07-11 02:22:39 +00:00
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
#ifdef GLQUAKE
|
|
|
|
if (qrenderer == QR_OPENGL)
|
2010-08-28 17:14:38 +00:00
|
|
|
{
|
|
|
|
int p;
|
|
|
|
for (p = 0; p < PERMUTATIONS; p++)
|
|
|
|
{
|
|
|
|
if (shader->programhandle[p].glsl)
|
|
|
|
GLSlang_DeleteObject(shader->programhandle[p].glsl);
|
|
|
|
}
|
|
|
|
}
|
2009-11-04 21:16:50 +00:00
|
|
|
#endif
|
|
|
|
memset(&shader->programhandle, 0, sizeof(shader->programhandle));
|
|
|
|
|
|
|
|
if (shader->skydome)
|
|
|
|
{
|
|
|
|
for (i = 0; i < 5; i++)
|
|
|
|
{
|
2005-04-16 16:21:27 +00:00
|
|
|
if (shader->skydome->meshes[i].xyz_array)
|
|
|
|
{
|
|
|
|
Z_Free ( shader->skydome->meshes[i].xyz_array );
|
|
|
|
Z_Free ( shader->skydome->meshes[i].normals_array );
|
|
|
|
Z_Free ( shader->skydome->meshes[i].st_array );
|
|
|
|
}
|
2004-10-19 15:56:22 +00:00
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
Z_Free (shader->skydome);
|
2005-04-16 16:21:27 +00:00
|
|
|
}
|
2004-10-19 15:56:22 +00:00
|
|
|
|
|
|
|
pass = shader->passes;
|
2009-11-04 21:16:50 +00:00
|
|
|
for (i = 0; i < shader->numpasses; i++, pass++)
|
|
|
|
{
|
|
|
|
Shader_FreePass (pass);
|
2004-10-19 15:56:22 +00:00
|
|
|
}
|
2010-07-11 02:22:39 +00:00
|
|
|
shader->numpasses = 0;
|
2004-10-19 15:56:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Shader_Shutdown (void)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
shader_t *shader;
|
|
|
|
shadercache_t *cache, *cache_next;
|
|
|
|
|
|
|
|
shader = r_shaders;
|
2010-07-25 15:12:12 +00:00
|
|
|
if (!r_shaders)
|
|
|
|
return; /*nothing needs freeing yet*/
|
2004-10-19 15:56:22 +00:00
|
|
|
for (i = 0; i < MAX_SHADERS; i++, shader++)
|
|
|
|
{
|
2010-07-11 02:22:39 +00:00
|
|
|
if ( !shader->uses )
|
2004-10-19 15:56:22 +00:00
|
|
|
continue;
|
2009-11-04 21:16:50 +00:00
|
|
|
|
2004-10-19 15:56:22 +00:00
|
|
|
Shader_Free ( shader );
|
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
for ( i = 0; i < HASH_SIZE; i++ )
|
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
cache = shader_hash[i];
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
for ( ; cache; cache = cache_next )
|
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
cache_next = cache->hash_next;
|
|
|
|
cache->hash_next = NULL;
|
|
|
|
Z_Free ( cache );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-07-11 02:22:39 +00:00
|
|
|
free(r_shaders);
|
2010-05-01 22:47:47 +00:00
|
|
|
r_shaders = NULL;
|
2010-07-11 02:22:39 +00:00
|
|
|
free(shader_hash);
|
2010-05-01 22:47:47 +00:00
|
|
|
shader_hash = NULL;
|
2010-07-11 02:22:39 +00:00
|
|
|
free(shader_active_hash_mem);
|
|
|
|
shader_active_hash_mem = NULL;
|
2009-11-04 21:16:50 +00:00
|
|
|
|
|
|
|
shader_reload_needed = false;
|
2004-10-19 15:56:22 +00:00
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
void Shader_SetBlendmode (shaderpass_t *pass)
|
2004-10-19 15:56:22 +00:00
|
|
|
{
|
2009-11-04 21:16:50 +00:00
|
|
|
if (pass->texgen == T_GEN_DELUXMAP)
|
|
|
|
{
|
|
|
|
pass->blendmode = GL_DOT3_RGB_ARB;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pass->texgen < T_GEN_DIFFUSE && !TEXVALID(pass->anim_frames[0]) && !(pass->flags & SHADER_PASS_LIGHTMAP))
|
|
|
|
{
|
|
|
|
pass->blendmode = GL_MODULATE;
|
2004-10-19 15:56:22 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2010-05-01 22:47:47 +00:00
|
|
|
if (!(pass->shaderbits & SBITS_BLEND_BITS))
|
2009-11-04 21:16:50 +00:00
|
|
|
{
|
|
|
|
if ((pass->rgbgen == RGB_GEN_IDENTITY) && (pass->alphagen == ALPHA_GEN_IDENTITY))
|
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
pass->blendmode = GL_REPLACE;
|
2009-11-04 21:16:50 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
#pragma message("is this correct?")
|
|
|
|
pass->shaderbits &= ~SBITS_BLEND_BITS;
|
|
|
|
pass->shaderbits |= SBITS_SRCBLEND_ONE;
|
|
|
|
pass->shaderbits |= SBITS_DSTBLEND_ZERO;
|
2004-10-19 15:56:22 +00:00
|
|
|
pass->blendmode = GL_MODULATE;
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
if (((pass->shaderbits&SBITS_BLEND_BITS) == (SBITS_SRCBLEND_ZERO|SBITS_DSTBLEND_SRC_COLOR)) ||
|
|
|
|
((pass->shaderbits&SBITS_BLEND_BITS) == (SBITS_SRCBLEND_DST_COLOR|SBITS_DSTBLEND_ZERO)))
|
2004-10-19 15:56:22 +00:00
|
|
|
pass->blendmode = GL_MODULATE;
|
2009-11-04 21:16:50 +00:00
|
|
|
else if ((pass->shaderbits&SBITS_BLEND_BITS) == (SBITS_SRCBLEND_ONE|SBITS_DSTBLEND_ONE))
|
2004-10-19 15:56:22 +00:00
|
|
|
pass->blendmode = GL_ADD;
|
2009-11-04 21:16:50 +00:00
|
|
|
else if ((pass->shaderbits&SBITS_BLEND_BITS) == (SBITS_SRCBLEND_SRC_ALPHA|SBITS_DSTBLEND_ONE_MINUS_SRC_ALPHA))
|
2004-10-19 15:56:22 +00:00
|
|
|
pass->blendmode = GL_DECAL;
|
|
|
|
else
|
2009-11-04 21:16:50 +00:00
|
|
|
pass->blendmode = GL_MODULATE;
|
2004-10-19 15:56:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Shader_Readpass (shader_t *shader, char **ptr)
|
|
|
|
{
|
|
|
|
char *token;
|
|
|
|
shaderpass_t *pass;
|
|
|
|
qboolean ignore;
|
|
|
|
static shader_t dummy;
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
if ( shader->numpasses >= SHADER_PASS_MAX )
|
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
ignore = true;
|
|
|
|
shader = &dummy;
|
|
|
|
shader->numpasses = 1;
|
|
|
|
pass = shader->passes;
|
2009-11-04 21:16:50 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
ignore = false;
|
|
|
|
pass = &shader->passes[shader->numpasses++];
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set defaults
|
|
|
|
pass->flags = 0;
|
2009-11-04 21:16:50 +00:00
|
|
|
pass->anim_frames[0] = r_nulltex;
|
2004-10-19 15:56:22 +00:00
|
|
|
pass->anim_numframes = 0;
|
|
|
|
pass->rgbgen = RGB_GEN_UNKNOWN;
|
|
|
|
pass->alphagen = ALPHA_GEN_IDENTITY;
|
|
|
|
pass->tcgen = TC_GEN_BASE;
|
|
|
|
pass->numtcmods = 0;
|
|
|
|
pass->numMergedPasses = 1;
|
|
|
|
|
2010-11-02 23:17:25 +00:00
|
|
|
if (shader->flags & SHADER_NOMIPMAPS)
|
|
|
|
pass->flags |= SHADER_PASS_NOMIPMAP;
|
|
|
|
|
2010-07-11 02:22:39 +00:00
|
|
|
while ( *ptr )
|
2004-10-19 15:56:22 +00:00
|
|
|
{
|
|
|
|
token = COM_ParseExt (ptr, true);
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
if ( !token[0] )
|
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
continue;
|
2009-11-04 21:16:50 +00:00
|
|
|
}
|
|
|
|
else if ( token[0] == '}' )
|
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
break;
|
2009-11-04 21:16:50 +00:00
|
|
|
}
|
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
|
|
|
else if (!Q_stricmp(token, "if"))
|
|
|
|
{
|
|
|
|
qboolean conditionistrue = Shader_EvaluateCondition(ptr);
|
|
|
|
|
|
|
|
while (*ptr)
|
|
|
|
{
|
|
|
|
token = COM_ParseExt (ptr, true);
|
|
|
|
if ( !token[0] )
|
|
|
|
continue;
|
|
|
|
else if (token[0] == ']')
|
|
|
|
break;
|
|
|
|
else if (conditionistrue)
|
|
|
|
{
|
|
|
|
Shader_Parsetok (shader, pass, shaderpasskeys, token, ptr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-11-04 21:16:50 +00:00
|
|
|
else if ( Shader_Parsetok (shader, pass, shaderpasskeys, token, ptr) )
|
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// check some things
|
2009-11-04 21:16:50 +00:00
|
|
|
if ( ignore )
|
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
Shader_Free ( shader );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
if ((pass->shaderbits&SBITS_BLEND_BITS) == (SBITS_SRCBLEND_ONE|SBITS_DSTBLEND_ZERO))
|
|
|
|
{
|
|
|
|
pass->shaderbits |= SBITS_MISC_DEPTHWRITE;
|
2004-10-19 15:56:22 +00:00
|
|
|
shader->flags |= SHADER_DEPTHWRITE;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (pass->rgbgen)
|
|
|
|
{
|
|
|
|
case RGB_GEN_IDENTITY_LIGHTING:
|
|
|
|
case RGB_GEN_IDENTITY:
|
|
|
|
case RGB_GEN_CONST:
|
|
|
|
case RGB_GEN_WAVE:
|
|
|
|
case RGB_GEN_ENTITY:
|
|
|
|
case RGB_GEN_ONE_MINUS_ENTITY:
|
|
|
|
case RGB_GEN_UNKNOWN: // assume RGB_GEN_IDENTITY or RGB_GEN_IDENTITY_LIGHTING
|
|
|
|
|
|
|
|
switch (pass->alphagen)
|
|
|
|
{
|
|
|
|
case ALPHA_GEN_IDENTITY:
|
|
|
|
case ALPHA_GEN_CONST:
|
|
|
|
case ALPHA_GEN_WAVE:
|
|
|
|
case ALPHA_GEN_ENTITY:
|
|
|
|
pass->flags |= SHADER_PASS_NOCOLORARRAY;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
if ((shader->flags & SHADER_SKY) && (shader->flags & SHADER_DEPTHWRITE))
|
|
|
|
{
|
|
|
|
#pragma message("is this valid?")
|
|
|
|
pass->shaderbits &= ~SBITS_MISC_DEPTHWRITE;
|
|
|
|
}
|
|
|
|
}
|
2004-10-19 15:56:22 +00:00
|
|
|
|
|
|
|
static qboolean Shader_Parsetok (shader_t *shader, shaderpass_t *pass, shaderkey_t *keys, char *token, char **ptr)
|
|
|
|
{
|
|
|
|
shaderkey_t *key;
|
|
|
|
|
|
|
|
for (key = keys; key->keyword != NULL; key++)
|
|
|
|
{
|
|
|
|
if (!Q_stricmp (token, key->keyword))
|
|
|
|
{
|
|
|
|
if (key->func)
|
|
|
|
key->func ( shader, pass, ptr );
|
|
|
|
|
|
|
|
return ( ptr && *ptr && **ptr == '}' );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Next Line
|
|
|
|
while (ptr)
|
|
|
|
{
|
|
|
|
token = COM_ParseExt ( ptr, false );
|
|
|
|
if ( !token[0] ) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
void Shader_SetPassFlush (shaderpass_t *pass, shaderpass_t *pass2)
|
2004-10-19 15:56:22 +00:00
|
|
|
{
|
2010-11-10 03:32:47 +00:00
|
|
|
qboolean config_tex_env_combine = 1;//0;
|
|
|
|
qboolean config_nv_tex_env_combine4 = 1;//0;
|
|
|
|
qboolean config_multitexure = be_maxpasses > 1;//0;
|
|
|
|
qboolean config_env_add = 1;//0;
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
if (((pass->flags & SHADER_PASS_DETAIL) && !r_detailtextures.value) ||
|
2004-10-19 15:56:22 +00:00
|
|
|
((pass2->flags & SHADER_PASS_DETAIL) && !r_detailtextures.value) ||
|
2010-08-14 00:15:07 +00:00
|
|
|
(pass->flags & SHADER_PASS_VIDEOMAP) || (pass2->flags & SHADER_PASS_VIDEOMAP))
|
2009-11-04 21:16:50 +00:00
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
if (pass2->rgbgen != RGB_GEN_IDENTITY || pass2->alphagen != ALPHA_GEN_IDENTITY)
|
2004-10-19 15:56:22 +00:00
|
|
|
return;
|
2009-11-04 21:16:50 +00:00
|
|
|
if (pass->rgbgen != RGB_GEN_IDENTITY || pass->alphagen != ALPHA_GEN_IDENTITY)
|
2004-10-19 15:56:22 +00:00
|
|
|
return;
|
|
|
|
|
2010-08-14 00:15:07 +00:00
|
|
|
/*if its alphatest, don't merge with anything other than lightmap*/
|
|
|
|
if ((pass->shaderbits & SBITS_ATEST_BITS) && (!(pass2->shaderbits & SBITS_MISC_DEPTHEQUALONLY) || pass2->texgen != T_GEN_LIGHTMAP))
|
|
|
|
return;
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
// check if we can use multiple passes
|
|
|
|
if (pass2->blendmode == GL_DOT3_RGB_ARB)
|
|
|
|
{
|
|
|
|
pass->numMergedPasses++;
|
|
|
|
}
|
2010-11-13 17:22:46 +00:00
|
|
|
else if (pass->numMergedPasses < be_maxpasses)
|
2004-10-19 15:56:22 +00:00
|
|
|
{
|
|
|
|
if ( pass->blendmode == GL_REPLACE )
|
|
|
|
{
|
2010-11-10 03:32:47 +00:00
|
|
|
if ((pass2->blendmode == GL_DECAL && config_tex_env_combine) ||
|
|
|
|
(pass2->blendmode == GL_ADD && config_env_add) ||
|
|
|
|
(pass2->blendmode && pass2->blendmode != GL_ADD) || config_nv_tex_env_combine4)
|
2004-10-19 15:56:22 +00:00
|
|
|
{
|
2009-11-04 21:16:50 +00:00
|
|
|
pass->numMergedPasses++;
|
2004-10-19 15:56:22 +00:00
|
|
|
}
|
|
|
|
}
|
2009-11-04 21:16:50 +00:00
|
|
|
else if (pass->blendmode == GL_ADD &&
|
2010-11-10 03:32:47 +00:00
|
|
|
pass2->blendmode == GL_ADD && config_env_add)
|
2004-10-19 15:56:22 +00:00
|
|
|
{
|
2009-11-04 21:16:50 +00:00
|
|
|
pass->numMergedPasses++;
|
|
|
|
}
|
|
|
|
else if (pass->blendmode == GL_MODULATE && pass2->blendmode == GL_MODULATE)
|
2004-10-19 15:56:22 +00:00
|
|
|
{
|
2009-11-04 21:16:50 +00:00
|
|
|
pass->numMergedPasses++;
|
2004-10-19 15:56:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Shader_SetFeatures ( shader_t *s )
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
qboolean trnormals;
|
|
|
|
shaderpass_t *pass;
|
|
|
|
|
|
|
|
s->features = MF_NONE;
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
for (i = 0, trnormals = true; i < s->numdeforms; i++)
|
|
|
|
{
|
|
|
|
switch (s->deforms[i].type)
|
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
case DEFORMV_BULGE:
|
|
|
|
case DEFORMV_WAVE:
|
|
|
|
trnormals = false;
|
|
|
|
case DEFORMV_NORMAL:
|
|
|
|
s->features |= MF_NORMALS;
|
|
|
|
break;
|
|
|
|
case DEFORMV_MOVE:
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
trnormals = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
if (trnormals)
|
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
s->features |= MF_TRNORMALS;
|
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
for (i = 0, pass = s->passes; i < s->numpasses; i++, pass++)
|
|
|
|
{
|
|
|
|
switch (pass->rgbgen)
|
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
case RGB_GEN_LIGHTING_DIFFUSE:
|
|
|
|
s->features |= MF_NORMALS;
|
|
|
|
break;
|
|
|
|
case RGB_GEN_VERTEX:
|
|
|
|
case RGB_GEN_ONE_MINUS_VERTEX:
|
|
|
|
case RGB_GEN_EXACT_VERTEX:
|
|
|
|
s->features |= MF_COLORS;
|
|
|
|
break;
|
2004-12-09 23:42:00 +00:00
|
|
|
default:
|
|
|
|
break;
|
2004-10-19 15:56:22 +00:00
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
switch ( pass->alphagen )
|
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
case ALPHA_GEN_SPECULAR:
|
|
|
|
s->features |= MF_NORMALS;
|
|
|
|
break;
|
|
|
|
case ALPHA_GEN_VERTEX:
|
|
|
|
s->features |= MF_COLORS;
|
|
|
|
break;
|
2004-12-09 23:42:00 +00:00
|
|
|
default:
|
|
|
|
break;
|
2004-10-19 15:56:22 +00:00
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
switch (pass->tcgen)
|
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
default:
|
|
|
|
s->features |= MF_STCOORDS;
|
|
|
|
break;
|
|
|
|
case TC_GEN_LIGHTMAP:
|
|
|
|
s->features |= MF_LMCOORDS;
|
|
|
|
break;
|
|
|
|
case TC_GEN_ENVIRONMENT:
|
2009-07-05 18:45:53 +00:00
|
|
|
case TC_GEN_NORMAL:
|
2004-10-19 15:56:22 +00:00
|
|
|
s->features |= MF_NORMALS;
|
|
|
|
break;
|
2009-11-04 21:16:50 +00:00
|
|
|
case TC_GEN_SVECTOR:
|
|
|
|
case TC_GEN_TVECTOR:
|
|
|
|
s->features |= MF_NORMALS;
|
|
|
|
break;
|
2004-10-19 15:56:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
void Shader_Finish (shader_t *s)
|
2004-10-19 15:56:22 +00:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
shaderpass_t *pass;
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
if (s->flags & SHADER_SKY && r_fastsky.ival)
|
|
|
|
{
|
|
|
|
s->flags = 0;
|
|
|
|
s->numdeforms = 0;
|
|
|
|
s->numpasses = 0;
|
|
|
|
s->numprogparams = 0;
|
|
|
|
|
|
|
|
Shader_DefaultScript(s->name, s,
|
|
|
|
"{\n"
|
|
|
|
"{\n"
|
|
|
|
"map $whiteimage\n"
|
2010-07-11 02:22:39 +00:00
|
|
|
"rgbgen const $r_fastskycolour\n"
|
2009-11-04 21:16:50 +00:00
|
|
|
"}\n"
|
2010-11-06 14:21:44 +00:00
|
|
|
"surfaceparm nodlight\n"
|
2009-11-04 21:16:50 +00:00
|
|
|
"}\n"
|
|
|
|
);
|
|
|
|
return;
|
2004-10-19 15:56:22 +00:00
|
|
|
}
|
|
|
|
|
2005-12-27 16:54:28 +00:00
|
|
|
if (!s->numpasses && !(s->flags & (SHADER_NODRAW|SHADER_SKY)) && !s->fog_dist)
|
2005-05-26 12:55:34 +00:00
|
|
|
{
|
|
|
|
pass = &s->passes[s->numpasses++];
|
|
|
|
pass = &s->passes[0];
|
|
|
|
pass->tcgen = TC_GEN_BASE;
|
2009-11-04 21:16:50 +00:00
|
|
|
pass->anim_frames[0] = R_LoadHiResTexture(s->name, NULL, IF_NOALPHA);
|
|
|
|
if (!TEXVALID(pass->anim_frames[0]))
|
2009-01-15 04:58:12 +00:00
|
|
|
{
|
|
|
|
Con_Printf("Shader %s failed to load default texture\n", s->name);
|
2006-01-12 22:24:06 +00:00
|
|
|
pass->anim_frames[0] = missing_texture;
|
2009-01-15 04:58:12 +00:00
|
|
|
}
|
2009-11-04 21:16:50 +00:00
|
|
|
pass->shaderbits |= SBITS_MISC_DEPTHWRITE;
|
2005-05-26 12:55:34 +00:00
|
|
|
pass->rgbgen = RGB_GEN_VERTEX;
|
|
|
|
pass->alphagen = ALPHA_GEN_IDENTITY;
|
|
|
|
pass->numMergedPasses = 1;
|
2009-11-04 21:16:50 +00:00
|
|
|
Shader_SetBlendmode(pass);
|
2005-05-26 12:55:34 +00:00
|
|
|
Con_Printf("Shader %s with no passes and no surfaceparm nodraw, inserting pass\n", s->name);
|
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
if (!Q_stricmp (s->name, "flareShader"))
|
|
|
|
{
|
|
|
|
s->flags |= SHADER_FLARE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!s->numpasses && !s->sort)
|
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
s->sort = SHADER_SORT_ADDITIVE;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
if (!s->sort && s->passes->texgen == T_GEN_CURRENTRENDER)
|
|
|
|
s->sort = SHADER_SORT_NEAREST;
|
|
|
|
|
|
|
|
|
|
|
|
if ((s->polyoffset.unit < 0) && !s->sort)
|
|
|
|
{
|
|
|
|
s->sort = SHADER_SORT_DECAL;
|
2004-10-19 15:56:22 +00:00
|
|
|
}
|
|
|
|
|
2010-08-28 17:14:38 +00:00
|
|
|
if (r_vertexlight.value && !s->programhandle[0].glsl)
|
2004-10-19 15:56:22 +00:00
|
|
|
{
|
|
|
|
// do we have a lightmap pass?
|
|
|
|
pass = s->passes;
|
2009-11-04 21:16:50 +00:00
|
|
|
for (i = 0; i < s->numpasses; i++, pass++)
|
2004-10-19 15:56:22 +00:00
|
|
|
{
|
2009-11-04 21:16:50 +00:00
|
|
|
if (pass->flags & SHADER_PASS_LIGHTMAP)
|
2004-10-19 15:56:22 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
if (i == s->numpasses)
|
2004-10-19 15:56:22 +00:00
|
|
|
{
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
// try to find pass with rgbgen set to RGB_GEN_VERTEX
|
|
|
|
pass = s->passes;
|
2009-11-04 21:16:50 +00:00
|
|
|
for (i = 0; i < s->numpasses; i++, pass++)
|
2004-10-19 15:56:22 +00:00
|
|
|
{
|
2009-11-04 21:16:50 +00:00
|
|
|
if (pass->rgbgen == RGB_GEN_VERTEX)
|
2004-10-19 15:56:22 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
if (i < s->numpasses)
|
2004-10-19 15:56:22 +00:00
|
|
|
{ // we found it
|
|
|
|
pass->flags |= SHADER_CULL_FRONT;
|
2009-11-04 21:16:50 +00:00
|
|
|
pass->flags &= ~SHADER_PASS_ANIMMAP;
|
|
|
|
pass->shaderbits &= ~SBITS_BLEND_BITS;
|
2004-10-19 15:56:22 +00:00
|
|
|
pass->blendmode = 0;
|
2009-11-04 21:16:50 +00:00
|
|
|
pass->shaderbits |= SBITS_MISC_DEPTHWRITE;
|
2004-10-19 15:56:22 +00:00
|
|
|
pass->alphagen = ALPHA_GEN_IDENTITY;
|
|
|
|
pass->numMergedPasses = 1;
|
|
|
|
s->flags |= SHADER_DEPTHWRITE;
|
|
|
|
s->sort = SHADER_SORT_OPAQUE;
|
|
|
|
s->numpasses = 1;
|
2009-11-04 21:16:50 +00:00
|
|
|
memcpy(&s->passes[0], pass, sizeof(shaderpass_t));
|
2004-10-19 15:56:22 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{ // we didn't find it - simply remove all lightmap passes
|
|
|
|
pass = s->passes;
|
2009-11-04 21:16:50 +00:00
|
|
|
for(i = 0; i < s->numpasses; i++, pass++)
|
2004-10-19 15:56:22 +00:00
|
|
|
{
|
2009-11-04 21:16:50 +00:00
|
|
|
if (pass->flags & SHADER_PASS_LIGHTMAP)
|
2004-10-19 15:56:22 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( i == s->numpasses -1 )
|
|
|
|
{
|
|
|
|
s->numpasses--;
|
|
|
|
}
|
|
|
|
else if ( i < s->numpasses - 1 )
|
|
|
|
{
|
|
|
|
for ( ; i < s->numpasses - 1; i++, pass++ )
|
|
|
|
{
|
|
|
|
memcpy ( pass, &s->passes[i+1], sizeof(shaderpass_t) );
|
|
|
|
}
|
|
|
|
s->numpasses--;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( s->passes[0].numtcmods )
|
|
|
|
{
|
|
|
|
pass = s->passes;
|
|
|
|
for ( i = 0; i < s->numpasses; i++, pass++ )
|
|
|
|
{
|
|
|
|
if ( !pass->numtcmods )
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
memcpy ( &s->passes[0], pass, sizeof(shaderpass_t) );
|
|
|
|
}
|
|
|
|
|
|
|
|
s->passes[0].rgbgen = RGB_GEN_VERTEX;
|
|
|
|
s->passes[0].alphagen = ALPHA_GEN_IDENTITY;
|
|
|
|
s->passes[0].blendmode = 0;
|
2009-11-04 21:16:50 +00:00
|
|
|
s->passes[0].flags &= ~(SHADER_PASS_ANIMMAP|SHADER_PASS_NOCOLORARRAY);
|
|
|
|
pass->shaderbits &= ~SBITS_BLEND_BITS;
|
|
|
|
s->passes[0].shaderbits |= SBITS_MISC_DEPTHWRITE;
|
2004-10-19 15:56:22 +00:00
|
|
|
s->passes[0].numMergedPasses = 1;
|
|
|
|
s->numpasses = 1;
|
|
|
|
s->flags |= SHADER_DEPTHWRITE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
done:;
|
|
|
|
|
|
|
|
pass = s->passes;
|
2009-11-04 21:16:50 +00:00
|
|
|
for (i = 0; i < s->numpasses; i++, pass++)
|
|
|
|
{
|
|
|
|
if (!(pass->shaderbits & SBITS_BLEND_BITS))
|
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// all passes have blendfuncs
|
2009-11-04 21:16:50 +00:00
|
|
|
if (i == s->numpasses)
|
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
int opaque;
|
|
|
|
|
|
|
|
opaque = -1;
|
|
|
|
pass = s->passes;
|
2009-11-04 21:16:50 +00:00
|
|
|
for (i = 0; i < s->numpasses; i++, pass++ )
|
|
|
|
{
|
2010-07-11 02:22:39 +00:00
|
|
|
if (pass->shaderbits & SBITS_ATEST_BITS)
|
2009-11-04 21:16:50 +00:00
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
opaque = i;
|
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
if (pass->rgbgen == RGB_GEN_UNKNOWN)
|
|
|
|
{
|
|
|
|
if (!s->fog_dist && !(pass->flags & SHADER_PASS_LIGHTMAP))
|
2004-10-19 15:56:22 +00:00
|
|
|
pass->rgbgen = RGB_GEN_IDENTITY_LIGHTING;
|
|
|
|
else
|
|
|
|
pass->rgbgen = RGB_GEN_IDENTITY;
|
|
|
|
}
|
2009-11-04 21:16:50 +00:00
|
|
|
|
|
|
|
Shader_SetBlendmode (pass);
|
2004-10-19 15:56:22 +00:00
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
if (!(s->flags & SHADER_SKY ) && !s->sort)
|
|
|
|
{
|
|
|
|
if (opaque == -1)
|
2010-07-11 02:22:39 +00:00
|
|
|
s->sort = SHADER_SORT_BLEND;
|
2004-10-19 15:56:22 +00:00
|
|
|
else
|
2010-07-11 02:22:39 +00:00
|
|
|
s->sort = SHADER_SORT_SEETHROUGH;
|
2004-10-19 15:56:22 +00:00
|
|
|
}
|
2009-11-04 21:16:50 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
int j;
|
|
|
|
shaderpass_t *sp;
|
|
|
|
|
|
|
|
sp = s->passes;
|
2009-11-04 21:16:50 +00:00
|
|
|
for (j = 0; j < s->numpasses; j++, sp++)
|
|
|
|
{
|
|
|
|
if (sp->rgbgen == RGB_GEN_UNKNOWN)
|
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
sp->rgbgen = RGB_GEN_IDENTITY;
|
|
|
|
}
|
2009-11-04 21:16:50 +00:00
|
|
|
|
|
|
|
Shader_SetBlendmode (sp);
|
2004-10-19 15:56:22 +00:00
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
if (!s->sort)
|
|
|
|
{
|
|
|
|
if (pass->shaderbits & SBITS_ATEST_BITS)
|
2010-07-11 02:22:39 +00:00
|
|
|
s->sort = SHADER_SORT_SEETHROUGH;
|
2004-10-19 15:56:22 +00:00
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
if (!( s->flags & SHADER_DEPTHWRITE) &&
|
|
|
|
!(s->flags & SHADER_SKY))
|
2004-10-19 15:56:22 +00:00
|
|
|
{
|
2009-11-04 21:16:50 +00:00
|
|
|
pass->shaderbits |= SBITS_MISC_DEPTHWRITE;
|
2004-10-19 15:56:22 +00:00
|
|
|
s->flags |= SHADER_DEPTHWRITE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
if (s->numpasses >= 2)
|
2004-10-19 15:56:22 +00:00
|
|
|
{
|
2009-11-04 21:16:50 +00:00
|
|
|
int j;
|
|
|
|
|
2004-10-19 15:56:22 +00:00
|
|
|
pass = s->passes;
|
2009-11-04 21:16:50 +00:00
|
|
|
for (i = 0; i < s->numpasses;)
|
2004-10-19 15:56:22 +00:00
|
|
|
{
|
2009-11-04 21:16:50 +00:00
|
|
|
if (i == s->numpasses - 1)
|
2004-10-19 15:56:22 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
pass = s->passes + i;
|
2009-11-04 21:16:50 +00:00
|
|
|
for (j = 1; j < s->numpasses-i && j == i + pass->numMergedPasses && j < be_maxpasses; j++)
|
|
|
|
Shader_SetPassFlush (pass, pass + j);
|
2004-10-19 15:56:22 +00:00
|
|
|
|
|
|
|
i += pass->numMergedPasses;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
if (!s->sort)
|
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
s->sort = SHADER_SORT_OPAQUE;
|
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
if ((s->flags & SHADER_SKY) && (s->flags & SHADER_DEPTHWRITE))
|
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
s->flags &= ~SHADER_DEPTHWRITE;
|
|
|
|
}
|
|
|
|
|
2010-08-28 17:14:38 +00:00
|
|
|
if (s->programhandle[0].glsl)
|
2006-03-11 03:12:10 +00:00
|
|
|
{
|
|
|
|
if (!s->numpasses)
|
|
|
|
s->numpasses = 1;
|
|
|
|
s->passes->numMergedPasses = s->numpasses;
|
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
Shader_SetFeatures(s);
|
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
|
|
|
|
|
|
|
#ifdef FORCEGLSL
|
|
|
|
BE_GenerateProgram(s);
|
|
|
|
#endif
|
2004-10-19 15:56:22 +00:00
|
|
|
}
|
|
|
|
/*
|
|
|
|
void Shader_UpdateRegistration (void)
|
|
|
|
{
|
|
|
|
int i, j, l;
|
|
|
|
shader_t *shader;
|
|
|
|
shaderpass_t *pass;
|
|
|
|
|
|
|
|
shader = r_shaders;
|
|
|
|
for (i = 0; i < MAX_SHADERS; i++, shader++)
|
|
|
|
{
|
2009-11-04 21:16:50 +00:00
|
|
|
if (!shader->registration_sequence)
|
2004-10-19 15:56:22 +00:00
|
|
|
continue;
|
2009-11-04 21:16:50 +00:00
|
|
|
if (shader->registration_sequence != registration_sequence)
|
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
Shader_Free ( shader );
|
|
|
|
shader->registration_sequence = 0;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
pass = shader->passes;
|
|
|
|
for (j = 0; j < shader->numpasses; j++, pass++)
|
|
|
|
{
|
2009-11-04 21:16:50 +00:00
|
|
|
if (pass->flags & SHADER_PASS_ANIMMAP)
|
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
for (l = 0; l < pass->anim_numframes; l++)
|
|
|
|
{
|
2009-11-04 21:16:50 +00:00
|
|
|
if (pass->anim_frames[l])
|
2004-10-19 15:56:22 +00:00
|
|
|
pass->anim_frames[l]->registration_sequence = registration_sequence;
|
|
|
|
}
|
2009-11-04 21:16:50 +00:00
|
|
|
}
|
|
|
|
else if ( pass->flags & SHADER_PASS_VIDEOMAP )
|
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
// Shader_RunCinematic will do the job
|
|
|
|
// pass->cin->frame = -1;
|
2009-11-04 21:16:50 +00:00
|
|
|
}
|
|
|
|
else if ( !(pass->flags & SHADER_PASS_LIGHTMAP) )
|
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
if ( pass->anim_frames[0] )
|
|
|
|
pass->anim_frames[0]->registration_sequence = registration_sequence;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
void R_BuildDefaultTexnums(texnums_t *tn, shader_t *shader)
|
2004-10-19 15:56:22 +00:00
|
|
|
{
|
2009-11-04 21:16:50 +00:00
|
|
|
extern cvar_t gl_bump;
|
2004-10-19 15:56:22 +00:00
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
/*dlights/realtime lighting needs some stuff*/
|
|
|
|
if (!TEXVALID(tn->base))
|
|
|
|
tn->base = R_LoadHiResTexture(shader->name, NULL, IF_NOALPHA);
|
2004-10-19 15:56:22 +00:00
|
|
|
|
2010-07-18 12:52:24 +00:00
|
|
|
if (gl_bump.ival)
|
|
|
|
{
|
|
|
|
if (!TEXVALID(tn->bump))
|
|
|
|
tn->bump = R_LoadHiResTexture(va("%s_norm", shader->name), NULL, IF_NOALPHA);
|
|
|
|
if (!TEXVALID(tn->bump))
|
|
|
|
tn->bump = R_LoadHiResTexture(va("%s_bump", shader->name), NULL, IF_NOALPHA);
|
|
|
|
if (!TEXVALID(tn->bump))
|
|
|
|
tn->bump = R_LoadHiResTexture(va("normalmaps/%s", shader->name), NULL, IF_NOALPHA);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (shader->flags & SHADER_HASTOPBOTTOM)
|
|
|
|
{
|
|
|
|
if (!TEXVALID(tn->loweroverlay))
|
|
|
|
tn->loweroverlay = R_LoadHiResTexture(va("%s_pants", shader->name), NULL, 0); /*how rude*/
|
|
|
|
if (!TEXVALID(tn->upperoverlay))
|
|
|
|
tn->upperoverlay = R_LoadHiResTexture(va("%s_shirt", shader->name), NULL, 0);
|
|
|
|
}
|
2004-10-19 15:56:22 +00:00
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
shader->defaulttextures = *tn;
|
2004-10-19 15:56:22 +00:00
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
void Shader_DefaultScript(char *shortname, shader_t *s, const void *args)
|
2005-03-20 02:57:11 +00:00
|
|
|
{
|
2009-11-04 21:16:50 +00:00
|
|
|
const char *f = args;
|
|
|
|
if (!args)
|
|
|
|
return;
|
|
|
|
while (*f == ' ' || *f == '\t' || *f == '\n' || *f == '\r')
|
|
|
|
f++;
|
|
|
|
if (*f == '{')
|
2009-07-18 20:46:42 +00:00
|
|
|
{
|
2009-11-04 21:16:50 +00:00
|
|
|
f++;
|
|
|
|
Shader_ReadShader(s, (void*)f);
|
2009-07-18 20:46:42 +00:00
|
|
|
}
|
2009-11-04 21:16:50 +00:00
|
|
|
};
|
2009-07-18 20:46:42 +00:00
|
|
|
|
2010-07-11 02:22:39 +00:00
|
|
|
void Shader_DefaultBSPLM(char *shortname, shader_t *s, const void *args)
|
2009-11-04 21:16:50 +00:00
|
|
|
{
|
|
|
|
char *builtin = NULL;
|
2010-07-11 02:22:39 +00:00
|
|
|
if (!builtin && r_drawflat.value)
|
|
|
|
builtin = (
|
|
|
|
"{\n"
|
|
|
|
"{\n"
|
|
|
|
"map $lightmap\n"
|
|
|
|
"tcgen lightmap\n"
|
|
|
|
"rgbgen const $r_floorcolour\n"
|
|
|
|
"}\n"
|
|
|
|
"}\n"
|
|
|
|
);
|
|
|
|
|
2010-11-02 23:17:25 +00:00
|
|
|
/* if (0&&!builtin && gl_config.arb_shader_objects)
|
2010-08-28 17:14:38 +00:00
|
|
|
{
|
|
|
|
builtin = (
|
|
|
|
"{\n"
|
|
|
|
"program default\n"
|
|
|
|
"param texture 0 tex_diffuse\n"
|
|
|
|
"param texture 1 tex_lightmap\n"
|
|
|
|
"param texture 2 tex_normalmap\n"
|
|
|
|
"param texture 3 tex_deluxmap\n"
|
|
|
|
"param texture 4 tex_fullbright\n"
|
|
|
|
"{\n"
|
|
|
|
"map $diffuse\n"
|
|
|
|
"tcgen base\n"
|
|
|
|
"}\n"
|
|
|
|
"{\n"
|
|
|
|
"map $lightmap\n"
|
|
|
|
"tcgen lightmap\n"
|
|
|
|
"}\n"
|
|
|
|
"{\n"
|
|
|
|
"map $normalmap\n"
|
|
|
|
"}\n"
|
|
|
|
"{\n"
|
|
|
|
"map $deluxmap\n"
|
|
|
|
"}\n"
|
|
|
|
"{\n"
|
|
|
|
"map $fullbright\n"
|
|
|
|
"}\n"
|
|
|
|
"}\n"
|
|
|
|
);
|
|
|
|
}
|
2010-11-02 23:17:25 +00:00
|
|
|
*/
|
2010-07-11 02:22:39 +00:00
|
|
|
if (!builtin)
|
|
|
|
builtin = (
|
|
|
|
"{\n"
|
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
|
|
|
"if gl_bump\n"
|
2010-07-11 02:22:39 +00:00
|
|
|
"[\n"
|
|
|
|
"{\n"
|
|
|
|
"map $normalmap\n"
|
|
|
|
"tcgen base\n"
|
2010-07-18 08:42:59 +00:00
|
|
|
"depthwrite\n"
|
2010-07-11 02:22:39 +00:00
|
|
|
"}\n"
|
|
|
|
"{\n"
|
|
|
|
"map $deluxmap\n"
|
|
|
|
"tcgen lightmap\n"
|
|
|
|
"}\n"
|
|
|
|
"]\n"
|
|
|
|
"{\n"
|
|
|
|
"map $diffuse\n"
|
|
|
|
"tcgen base\n"
|
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
|
|
|
"if gl_bump\n"
|
2010-07-18 08:42:59 +00:00
|
|
|
"[\n"
|
|
|
|
"blendfunc gl_one gl_zero\n"
|
|
|
|
"]\n"
|
2010-07-11 02:22:39 +00:00
|
|
|
"}\n"
|
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
|
|
|
"if !r_fullbright\n"
|
2010-07-11 02:22:39 +00:00
|
|
|
"[\n"
|
|
|
|
"{\n"
|
|
|
|
"map $lightmap\n"
|
|
|
|
"blendfunc gl_dst_color gl_zero\n"
|
|
|
|
"}\n"
|
|
|
|
"]\n"
|
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
|
|
|
"if gl_fb_bmodels\n"
|
2010-07-18 08:42:59 +00:00
|
|
|
"[\n"
|
|
|
|
"{\n"
|
|
|
|
"map $fullbright\n"
|
|
|
|
"blendfunc add\n"
|
|
|
|
"depthfunc equal\n"
|
|
|
|
"}\n"
|
|
|
|
"]\n"
|
2010-07-11 02:22:39 +00:00
|
|
|
"}\n"
|
|
|
|
);
|
|
|
|
|
|
|
|
Shader_DefaultScript(shortname, s, builtin);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Shader_DefaultCinematic(char *shortname, shader_t *s, const void *args)
|
|
|
|
{
|
|
|
|
Shader_DefaultScript(shortname, s,
|
|
|
|
va(
|
|
|
|
"{\n"
|
|
|
|
"{\n"
|
|
|
|
"videomap %s\n"
|
|
|
|
"}\n"
|
|
|
|
"}\n"
|
|
|
|
, args)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*shortname should begin with 'skybox_'*/
|
|
|
|
void Shader_DefaultSkybox(char *shortname, shader_t *s, const void *args)
|
|
|
|
{
|
|
|
|
Shader_DefaultScript(shortname, s,
|
|
|
|
va(
|
|
|
|
"{\n"
|
|
|
|
"skyparms %s - -\n"
|
|
|
|
"}\n"
|
|
|
|
, shortname+7)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Shader_DefaultBSPQ2(char *shortname, shader_t *s, const void *args)
|
|
|
|
{
|
|
|
|
if (!strncmp(shortname, "sky/", 4))
|
2009-07-18 20:46:42 +00:00
|
|
|
{
|
2010-07-11 02:22:39 +00:00
|
|
|
Shader_DefaultScript(shortname, s,
|
|
|
|
"{\n"
|
|
|
|
"skyparms - - -\n"
|
|
|
|
"}\n"
|
|
|
|
);
|
2009-07-18 20:46:42 +00:00
|
|
|
}
|
2010-07-11 02:22:39 +00:00
|
|
|
else if (!strncmp(shortname, "warp/", 7))
|
|
|
|
{
|
|
|
|
Shader_DefaultScript(shortname, s,
|
|
|
|
"{\n"
|
|
|
|
"{\n"
|
|
|
|
"map $diffuse\n"
|
|
|
|
"tcmod turb 0 0.01 0.5 0\n"
|
|
|
|
"}\n"
|
|
|
|
"}\n"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
else if (!strncmp(shortname, "warp33/", 7))
|
|
|
|
{
|
|
|
|
Shader_DefaultScript(shortname, s,
|
|
|
|
"{\n"
|
|
|
|
"{\n"
|
|
|
|
"map $diffuse\n"
|
|
|
|
"tcmod turb 0 0.01 0.5 0\n"
|
|
|
|
"alphagen const 0.333\n"
|
|
|
|
"blendfunc blend\n"
|
|
|
|
"}\n"
|
|
|
|
"}\n"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
else if (!strncmp(shortname, "warp66/", 7))
|
|
|
|
{
|
|
|
|
Shader_DefaultScript(shortname, s,
|
|
|
|
"{\n"
|
|
|
|
"{\n"
|
|
|
|
"map $diffuse\n"
|
|
|
|
"tcmod turb 0 0.01 0.5 0\n"
|
|
|
|
"alphagen const 0.666\n"
|
|
|
|
"blendfunc blend\n"
|
|
|
|
"}\n"
|
|
|
|
"}\n"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
else if (!strncmp(shortname, "trans/", 7))
|
|
|
|
Shader_DefaultScript(shortname, s,
|
|
|
|
"{\n"
|
|
|
|
"{\n"
|
|
|
|
"map $diffuse\n"
|
|
|
|
"alphagen const 1\n"
|
|
|
|
"blendfunc blend\n"
|
|
|
|
"}\n"
|
|
|
|
"}\n"
|
|
|
|
);
|
|
|
|
else if (!strncmp(shortname, "trans33/", 7))
|
|
|
|
Shader_DefaultScript(shortname, s,
|
|
|
|
"{\n"
|
|
|
|
"{\n"
|
|
|
|
"map $diffuse\n"
|
|
|
|
"alphagen const 0.333\n"
|
|
|
|
"blendfunc blend\n"
|
|
|
|
"}\n"
|
|
|
|
"}\n"
|
|
|
|
);
|
|
|
|
else if (!strncmp(shortname, "trans66/", 7))
|
|
|
|
Shader_DefaultScript(shortname, s,
|
|
|
|
"{\n"
|
|
|
|
"{\n"
|
|
|
|
"map $diffuse\n"
|
|
|
|
"alphagen const 0.666\n"
|
|
|
|
"blendfunc blend\n"
|
|
|
|
"}\n"
|
|
|
|
"}\n"
|
|
|
|
);
|
|
|
|
else
|
|
|
|
Shader_DefaultBSPLM(shortname, s, args);
|
|
|
|
}
|
2009-07-18 20:46:42 +00:00
|
|
|
|
2010-07-11 02:22:39 +00:00
|
|
|
void Shader_DefaultBSPQ1(char *shortname, shader_t *s, const void *args)
|
|
|
|
{
|
|
|
|
char *builtin = NULL;
|
|
|
|
if (r_mirroralpha.value < 1 && !strcmp(shortname, "window02_1"))
|
2005-03-20 02:57:11 +00:00
|
|
|
{
|
2010-07-11 02:22:39 +00:00
|
|
|
if (r_mirroralpha.value < 0)
|
2009-06-21 17:45:33 +00:00
|
|
|
{
|
2010-07-11 02:22:39 +00:00
|
|
|
builtin = "{\n"
|
|
|
|
"portal\n"
|
|
|
|
"{\n"
|
|
|
|
"map $diffuse\n"
|
|
|
|
"blendfunc blend\n"
|
|
|
|
"alphagen portal 512\n"
|
|
|
|
"depthwrite\n"
|
|
|
|
"}\n"
|
|
|
|
"}\n";
|
2009-06-21 17:45:33 +00:00
|
|
|
}
|
2006-03-06 01:41:09 +00:00
|
|
|
else
|
2010-07-11 02:22:39 +00:00
|
|
|
{
|
|
|
|
builtin = "{\n"
|
|
|
|
"portal\n"
|
|
|
|
"{\n"
|
|
|
|
"map $diffuse\n"
|
|
|
|
"blendfunc blend\n"
|
|
|
|
"alphagen const $r_mirroralpha\n"
|
|
|
|
"depthwrite\n"
|
|
|
|
"}\n"
|
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
|
|
|
"surfaceparm nodlight\n"
|
2010-07-11 02:22:39 +00:00
|
|
|
"}\n";
|
|
|
|
}
|
2006-03-06 01:41:09 +00:00
|
|
|
|
2005-03-20 02:57:11 +00:00
|
|
|
}
|
2006-03-06 01:41:09 +00:00
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
if (!builtin && (*shortname == '*'))
|
2009-07-18 20:46:42 +00:00
|
|
|
{
|
2009-11-04 21:16:50 +00:00
|
|
|
//q1 water
|
2010-07-11 02:22:39 +00:00
|
|
|
if (r_fastturb.ival)
|
2009-07-18 20:46:42 +00:00
|
|
|
{
|
2010-07-11 02:22:39 +00:00
|
|
|
builtin = (
|
|
|
|
"{\n"
|
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
|
|
|
"sort seethrough\n"
|
2009-11-04 21:16:50 +00:00
|
|
|
"{\n"
|
2010-07-11 02:22:39 +00:00
|
|
|
"map $whiteimage\n"
|
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
|
|
|
"rgbgen const $r_fastturbcolour\n"
|
2009-11-04 21:16:50 +00:00
|
|
|
"}\n"
|
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
|
|
|
"surfaceparm nodlight\n"
|
2010-07-11 02:22:39 +00:00
|
|
|
"}\n"
|
|
|
|
);
|
2009-11-04 21:16:50 +00:00
|
|
|
}
|
2010-07-11 02:22:39 +00:00
|
|
|
#ifdef GLQUAKE
|
|
|
|
else if (qrenderer == QR_OPENGL && gl_config.arb_shader_objects)
|
|
|
|
{
|
2009-11-04 21:16:50 +00:00
|
|
|
builtin = (
|
|
|
|
"{\n"
|
|
|
|
"program\n"
|
|
|
|
"{\n"
|
|
|
|
"#ifdef VERTEX_SHADER\n"
|
|
|
|
"varying vec3 pos;\n"
|
|
|
|
"varying vec2 tc;\n"
|
|
|
|
|
|
|
|
"void main (void)\n"
|
|
|
|
"{\n"
|
|
|
|
" tc = gl_MultiTexCoord0.st;\n"
|
|
|
|
" gl_Position = ftransform();\n"
|
|
|
|
"}\n"
|
|
|
|
"#endif\n"
|
|
|
|
|
|
|
|
"#ifdef FRAGMENT_SHADER\n"
|
|
|
|
"uniform sampler2D watertexture;\n"
|
|
|
|
"uniform float time;\n"
|
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
|
|
|
"uniform float wateralpha;\n"
|
2009-11-04 21:16:50 +00:00
|
|
|
"varying vec2 tc;\n"
|
|
|
|
|
|
|
|
"void main (void)\n"
|
|
|
|
"{\n"
|
|
|
|
" vec2 ntc;\n"
|
|
|
|
" ntc.s = tc.s + sin(tc.t+time)*0.125;\n"
|
|
|
|
" ntc.t = tc.t + sin(tc.s+time)*0.125;\n"
|
|
|
|
" vec3 ts = vec3(texture2D(watertexture, ntc));\n"
|
|
|
|
|
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
|
|
|
" gl_FragColor = vec4(ts, wateralpha);\n"
|
2009-11-04 21:16:50 +00:00
|
|
|
"}\n"
|
|
|
|
"#endif\n"
|
|
|
|
"}\n"
|
|
|
|
"param time time\n"
|
|
|
|
"param texture 0 watertexture\n"
|
2010-11-10 03:32:47 +00:00
|
|
|
"if r_wateralpha != 1\n"
|
|
|
|
"[\n"
|
|
|
|
"param cvarf r_wateralpha wateralpha\n"
|
|
|
|
"sort blend\n"
|
|
|
|
"{\n"
|
|
|
|
"map $diffuse\n"
|
|
|
|
"blendfunc gl_src_alpha gl_one_minus_src_alpha\n"
|
|
|
|
"}\n"
|
|
|
|
"]\n"
|
|
|
|
"if r_wateralpha == 1\n"
|
|
|
|
"[\n"
|
|
|
|
"param constf 1 wateralpha\n"
|
|
|
|
"sort opaque\n"
|
|
|
|
"{\n"
|
|
|
|
"map $diffuse\n"
|
|
|
|
"}\n"
|
|
|
|
"]\n"
|
2009-11-04 21:16:50 +00:00
|
|
|
"surfaceparm nodlight\n"
|
|
|
|
"}\n"
|
|
|
|
);
|
2006-03-06 01:41:09 +00:00
|
|
|
}
|
2010-07-11 02:22:39 +00:00
|
|
|
#endif
|
2006-03-06 01:41:09 +00:00
|
|
|
else
|
|
|
|
{
|
2010-07-11 02:22:39 +00:00
|
|
|
builtin = (
|
|
|
|
"{\n"
|
|
|
|
"{\n"
|
|
|
|
"map $diffuse\n"
|
|
|
|
"tcmod turb 0 0.01 0.5 0\n"
|
|
|
|
"}\n"
|
|
|
|
"}\n"
|
|
|
|
);
|
2006-03-06 01:41:09 +00:00
|
|
|
}
|
2009-11-04 21:16:50 +00:00
|
|
|
}
|
|
|
|
if (!builtin && !strncmp(shortname, "sky", 3))
|
2005-03-20 02:57:11 +00:00
|
|
|
{
|
2009-11-04 21:16:50 +00:00
|
|
|
//q1 sky
|
|
|
|
if (r_fastsky.ival)
|
|
|
|
builtin = (
|
|
|
|
"{\n"
|
|
|
|
"{\n"
|
|
|
|
"map $whiteimage\n"
|
2010-07-11 02:22:39 +00:00
|
|
|
"rgbgen const $r_fastskycolour\n"
|
2009-11-04 21:16:50 +00:00
|
|
|
"}\n"
|
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
|
|
|
"surfaceparm nodlight\n"
|
2009-11-04 21:16:50 +00:00
|
|
|
"}\n"
|
|
|
|
);
|
|
|
|
else if (*r_skyboxname.string)
|
|
|
|
builtin = (
|
|
|
|
"{\n"
|
|
|
|
"skyparms $r_skybox - -\n"
|
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
|
|
|
"surfaceparm nodlight\n"
|
2009-11-04 21:16:50 +00:00
|
|
|
"}\n"
|
|
|
|
);
|
2010-07-11 02:22:39 +00:00
|
|
|
#ifdef GLQUAKE
|
|
|
|
else if (qrenderer == QR_OPENGL && gl_config.arb_shader_objects)
|
2009-11-04 21:16:50 +00:00
|
|
|
builtin = (
|
|
|
|
"{\n"
|
|
|
|
"program\n"
|
|
|
|
"{\n"
|
|
|
|
"#ifdef VERTEX_SHADER\n"
|
|
|
|
"varying vec3 pos;\n"
|
|
|
|
|
|
|
|
"void main (void)\n"
|
|
|
|
"{\n"
|
|
|
|
" pos = gl_Vertex.xyz;\n"
|
|
|
|
" gl_Position = ftransform();\n"
|
|
|
|
"}\n"
|
|
|
|
"#endif\n"
|
|
|
|
|
|
|
|
"#ifdef FRAGMENT_SHADER\n"
|
|
|
|
"uniform sampler2D solidt;\n"
|
|
|
|
"uniform sampler2D transt;\n"
|
|
|
|
|
|
|
|
"uniform float time;\n"
|
|
|
|
"uniform vec3 eyepos;\n"
|
|
|
|
"varying vec3 pos;\n"
|
|
|
|
|
|
|
|
"void main (void)\n"
|
|
|
|
"{\n"
|
|
|
|
" vec2 tccoord;\n"
|
|
|
|
|
|
|
|
" vec3 dir = pos - eyepos;\n"
|
|
|
|
|
|
|
|
" dir.z *= 3.0;\n"
|
|
|
|
" dir.xy /= 0.5*length(dir);\n"
|
|
|
|
|
|
|
|
" tccoord = (dir.xy + time*0.03125);\n"
|
|
|
|
" vec3 solid = vec3(texture2D(solidt, tccoord));\n"
|
|
|
|
|
|
|
|
" tccoord = (dir.xy + time*0.0625);\n"
|
|
|
|
" vec4 clouds = texture2D(transt, tccoord);\n"
|
|
|
|
|
|
|
|
" gl_FragColor.rgb = (solid.rgb*(1.0-clouds.a)) + (clouds.a*clouds.rgb);\n"
|
|
|
|
// " gl_FragColor.rgb = solid.rgb;/*gl_FragColor.g = clouds.r;*/gl_FragColor.b = clouds.a;\n"
|
|
|
|
"}\n"
|
|
|
|
"#endif\n"
|
|
|
|
"}\n"
|
|
|
|
"param time time\n"
|
|
|
|
"param eyepos eyepos\n"
|
|
|
|
"param texture 0 solidt\n"
|
|
|
|
"param texture 1 transt\n"
|
|
|
|
"surfaceparm nodlight\n"
|
|
|
|
//"skyparms - 512 -\n"
|
|
|
|
"{\n"
|
|
|
|
"map $diffuse\n"
|
|
|
|
"}\n"
|
|
|
|
"{\n"
|
|
|
|
"map $fullbright\n"
|
|
|
|
"}\n"
|
|
|
|
"}\n"
|
|
|
|
);
|
2010-07-11 02:22:39 +00:00
|
|
|
#endif
|
|
|
|
else
|
|
|
|
builtin = (
|
|
|
|
"{\n"
|
|
|
|
"skyparms - 512 -\n"
|
|
|
|
/*WARNING: these values are not authentic quake, only close aproximations*/
|
|
|
|
"{\n"
|
|
|
|
"map $diffuse\n"
|
|
|
|
"tcmod scale 10 10\n"
|
|
|
|
"tcmod scroll 0.04 0.04\n"
|
|
|
|
"}\n"
|
|
|
|
"{\n"
|
|
|
|
"map $fullbright\n"
|
|
|
|
"blendfunc blend\n"
|
|
|
|
"tcmod scale 10 10\n"
|
|
|
|
"tcmod scroll 0.02 0.02\n"
|
|
|
|
"}\n"
|
|
|
|
"}\n"
|
|
|
|
);
|
2009-11-04 21:16:50 +00:00
|
|
|
}
|
|
|
|
if (!builtin && *shortname == '{')
|
2006-03-06 01:41:09 +00:00
|
|
|
{
|
2009-11-04 21:16:50 +00:00
|
|
|
/*alpha test*/
|
|
|
|
builtin = (
|
|
|
|
"{\n"
|
|
|
|
/* "if $deluxmap\n"
|
|
|
|
"[\n"
|
|
|
|
"{\n"
|
|
|
|
"map $normalmap\n"
|
|
|
|
"tcgen base\n"
|
|
|
|
"}\n"
|
|
|
|
"{\n"
|
|
|
|
"map $deluxmap\n"
|
|
|
|
"tcgen lightmap\n"
|
|
|
|
"}\n"
|
|
|
|
"]\n"*/
|
|
|
|
"{\n"
|
|
|
|
"map $diffuse\n"
|
|
|
|
"tcgen base\n"
|
|
|
|
"alphamask\n"
|
|
|
|
"}\n"
|
|
|
|
"if $lightmap\n"
|
|
|
|
"[\n"
|
|
|
|
"{\n"
|
|
|
|
"map $lightmap\n"
|
|
|
|
"blendfunc gl_dst_color gl_zero\n"
|
|
|
|
"depthfunc equal\n"
|
|
|
|
"}\n"
|
|
|
|
"]\n"
|
|
|
|
"{\n"
|
|
|
|
"map $fullbright\n"
|
|
|
|
"blendfunc add\n"
|
|
|
|
"depthfunc equal\n"
|
|
|
|
"}\n"
|
|
|
|
"}\n"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*Hack: note that halflife would normally expect you to use rendermode/renderampt*/
|
2010-07-11 02:22:39 +00:00
|
|
|
if (!builtin && (!strncmp(shortname, "glass", 5)/* || !strncmp(shortname, "window", 6)*/))
|
2005-05-26 12:55:34 +00:00
|
|
|
{
|
2009-11-04 21:16:50 +00:00
|
|
|
/*alpha bended*/
|
|
|
|
builtin = (
|
|
|
|
"{\n"
|
|
|
|
"{\n"
|
|
|
|
"map $diffuse\n"
|
|
|
|
"tcgen base\n"
|
|
|
|
"blendfunc blend\n"
|
|
|
|
"}\n"
|
|
|
|
"}\n"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2010-07-11 02:22:39 +00:00
|
|
|
if (builtin)
|
|
|
|
Shader_DefaultScript(shortname, s, builtin);
|
|
|
|
else
|
|
|
|
Shader_DefaultBSPLM(shortname, s, args);
|
2009-11-04 21:16:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Shader_DefaultBSPVertex(char *shortname, shader_t *s, const void *args)
|
2005-03-20 02:57:11 +00:00
|
|
|
{
|
|
|
|
shaderpass_t *pass;
|
|
|
|
pass = &s->passes[0];
|
|
|
|
pass->tcgen = TC_GEN_BASE;
|
2009-11-04 21:16:50 +00:00
|
|
|
pass->anim_frames[0] = R_LoadHiResTexture(shortname, NULL, 0);
|
|
|
|
pass->shaderbits |= SBITS_MISC_DEPTHWRITE;
|
2005-03-20 02:57:11 +00:00
|
|
|
pass->rgbgen = RGB_GEN_VERTEX;
|
|
|
|
pass->alphagen = ALPHA_GEN_IDENTITY;
|
|
|
|
pass->numMergedPasses = 1;
|
2009-11-04 21:16:50 +00:00
|
|
|
Shader_SetBlendmode(pass);
|
2005-03-20 02:57:11 +00:00
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
if (!TEXVALID(pass->anim_frames[0]))
|
|
|
|
{
|
2007-09-23 15:28:06 +00:00
|
|
|
Con_DPrintf (CON_WARNING "Shader %s has a stage with no image: %s.\n", s->name, shortname );
|
2006-03-06 01:41:09 +00:00
|
|
|
pass->anim_frames[0] = missing_texture;
|
2005-03-20 02:57:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
s->numpasses = 1;
|
|
|
|
s->numdeforms = 0;
|
|
|
|
s->flags = SHADER_DEPTHWRITE|SHADER_CULL_FRONT;
|
2009-11-04 21:16:50 +00:00
|
|
|
s->features = MF_STCOORDS|MF_COLORS;
|
2005-03-20 02:57:11 +00:00
|
|
|
s->sort = SHADER_SORT_OPAQUE;
|
2010-07-11 02:22:39 +00:00
|
|
|
s->uses = 1;
|
2005-03-20 02:57:11 +00:00
|
|
|
}
|
2009-11-04 21:16:50 +00:00
|
|
|
void Shader_DefaultBSPFlare(char *shortname, shader_t *s, const void *args)
|
2005-03-20 02:57:11 +00:00
|
|
|
{
|
|
|
|
shaderpass_t *pass;
|
|
|
|
pass = &s->passes[0];
|
2009-11-04 21:16:50 +00:00
|
|
|
pass->flags = SHADER_PASS_NOCOLORARRAY;
|
|
|
|
pass->shaderbits |= SBITS_SRCBLEND_ONE|SBITS_DSTBLEND_ONE;
|
|
|
|
pass->anim_frames[0] = R_LoadHiResTexture(shortname, NULL, 0);
|
2005-03-20 02:57:11 +00:00
|
|
|
pass->rgbgen = RGB_GEN_VERTEX;
|
|
|
|
pass->alphagen = ALPHA_GEN_IDENTITY;
|
|
|
|
pass->numtcmods = 0;
|
|
|
|
pass->tcgen = TC_GEN_BASE;
|
|
|
|
pass->numMergedPasses = 1;
|
2009-11-04 21:16:50 +00:00
|
|
|
Shader_SetBlendmode(pass);
|
2005-03-20 02:57:11 +00:00
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
if (!TEXVALID(pass->anim_frames[0]))
|
|
|
|
{
|
2007-09-23 15:28:06 +00:00
|
|
|
Con_DPrintf (CON_WARNING "Shader %s has a stage with no image: %s.\n", s->name, shortname );
|
2006-03-06 01:41:09 +00:00
|
|
|
pass->anim_frames[0] = missing_texture;
|
2005-03-20 02:57:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
s->numpasses = 1;
|
|
|
|
s->numdeforms = 0;
|
|
|
|
s->flags = SHADER_FLARE;
|
|
|
|
s->features = MF_STCOORDS|MF_COLORS;
|
|
|
|
s->sort = SHADER_SORT_ADDITIVE;
|
2010-07-11 02:22:39 +00:00
|
|
|
s->uses = 1;
|
2005-03-20 02:57:11 +00:00
|
|
|
}
|
2009-11-04 21:16:50 +00:00
|
|
|
void Shader_DefaultSkin(char *shortname, shader_t *s, const void *args)
|
|
|
|
{
|
|
|
|
Shader_DefaultScript(shortname, s,
|
|
|
|
"{\n"
|
|
|
|
"{\n"
|
|
|
|
"map $diffuse\n"
|
|
|
|
"rgbgen lightingDiffuse\n"
|
|
|
|
"}\n"
|
|
|
|
"{\n"
|
|
|
|
"map $loweroverlay\n"
|
|
|
|
"rgbgen bottomcolor\n"
|
2010-07-11 02:22:39 +00:00
|
|
|
"blendfunc gl_src_alpha gl_one\n"
|
2009-11-04 21:16:50 +00:00
|
|
|
"}\n"
|
|
|
|
"{\n"
|
|
|
|
"map $upperoverlay\n"
|
2010-07-11 02:22:39 +00:00
|
|
|
"rgbgen topcolor\n"
|
|
|
|
"blendfunc gl_src_alpha gl_one\n"
|
2009-11-04 21:16:50 +00:00
|
|
|
"}\n"
|
|
|
|
"{\n"
|
|
|
|
"map $fullbright\n"
|
|
|
|
"blendfunc add\n"
|
|
|
|
"}\n"
|
|
|
|
"}\n"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
void Shader_DefaultSkinShell(char *shortname, shader_t *s, const void *args)
|
2005-03-20 02:57:11 +00:00
|
|
|
{
|
|
|
|
shaderpass_t *pass;
|
|
|
|
pass = &s->passes[0];
|
2009-11-04 21:16:50 +00:00
|
|
|
pass->shaderbits |= SBITS_MISC_DEPTHWRITE;
|
|
|
|
pass->anim_frames[0] = R_LoadHiResTexture(shortname, NULL, 0);
|
|
|
|
if (!TEXVALID(pass->anim_frames[0]))
|
2006-01-12 22:24:06 +00:00
|
|
|
pass->anim_frames[0] = missing_texture;
|
2005-03-20 02:57:11 +00:00
|
|
|
pass->rgbgen = RGB_GEN_ENTITY;
|
|
|
|
pass->alphagen = ALPHA_GEN_ENTITY;
|
|
|
|
pass->numtcmods = 0;
|
|
|
|
pass->tcgen = TC_GEN_BASE;
|
2009-11-04 21:16:50 +00:00
|
|
|
pass->shaderbits |= SBITS_SRCBLEND_SRC_ALPHA;
|
|
|
|
pass->shaderbits |= SBITS_DSTBLEND_ONE_MINUS_SRC_ALPHA;
|
2005-03-20 02:57:11 +00:00
|
|
|
pass->numMergedPasses = 1;
|
2009-11-04 21:16:50 +00:00
|
|
|
Shader_SetBlendmode(pass);
|
2005-03-20 02:57:11 +00:00
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
if (!TEXVALID(pass->anim_frames[0]))
|
|
|
|
{
|
2007-09-23 15:28:06 +00:00
|
|
|
Con_DPrintf (CON_WARNING "Shader %s has a stage with no image: %s.\n", s->name, shortname );
|
2006-03-06 01:41:09 +00:00
|
|
|
pass->anim_frames[0] = missing_texture;
|
2005-03-20 02:57:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
s->numpasses = 1;
|
|
|
|
s->numdeforms = 0;
|
|
|
|
s->flags = SHADER_DEPTHWRITE|SHADER_CULL_FRONT;
|
|
|
|
s->features = MF_STCOORDS|MF_NORMALS;
|
|
|
|
s->sort = SHADER_SORT_OPAQUE;
|
2010-07-11 02:22:39 +00:00
|
|
|
s->uses = 1;
|
2005-03-20 02:57:11 +00:00
|
|
|
}
|
2009-11-04 21:16:50 +00:00
|
|
|
void Shader_Default2D(char *shortname, shader_t *s, const void *genargs)
|
2005-03-20 02:57:11 +00:00
|
|
|
{
|
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
|
|
|
Shader_DefaultScript(shortname, s,
|
|
|
|
"{\n"
|
2010-11-02 23:17:25 +00:00
|
|
|
"nomipmaps\n"
|
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
|
|
|
"{\n"
|
|
|
|
"map $diffuse\n"
|
|
|
|
"rgbgen vertex\n"
|
|
|
|
"alphagen vertex\n"
|
|
|
|
"blendfunc gl_src_alpha gl_one_minus_src_alpha\n"
|
|
|
|
"}\n"
|
|
|
|
"sort additive\n"
|
|
|
|
"}\n"
|
|
|
|
);
|
|
|
|
|
|
|
|
s->defaulttextures.base = R_LoadHiResTexture(shortname, NULL, IF_NOPICMIP|IF_NOMIPMAP);
|
2010-11-02 23:17:25 +00:00
|
|
|
if (!TEXVALID(s->defaulttextures.base))
|
|
|
|
{
|
|
|
|
unsigned char data[4*4] = {0};
|
|
|
|
s->defaulttextures.base = R_LoadTexture8("black", 4, 4, data, 0, 0);
|
|
|
|
}
|
2009-11-04 21:16:50 +00:00
|
|
|
s->width = image_width;
|
|
|
|
s->height = image_height;
|
2005-03-20 02:57:11 +00:00
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
//loads a shader string into an existing shader object, and finalises it and stuff
|
|
|
|
static void Shader_ReadShader(shader_t *s, char *shadersource)
|
|
|
|
{
|
|
|
|
char *token;
|
|
|
|
|
|
|
|
// set defaults
|
|
|
|
s->flags = SHADER_CULL_FRONT;
|
2010-07-11 02:22:39 +00:00
|
|
|
s->uses = 1;
|
2009-11-04 21:16:50 +00:00
|
|
|
|
|
|
|
while (shadersource)
|
|
|
|
{
|
|
|
|
token = COM_ParseExt (&shadersource, true);
|
|
|
|
|
|
|
|
if ( !token[0] )
|
|
|
|
continue;
|
|
|
|
else if ( token[0] == '}' )
|
|
|
|
break;
|
|
|
|
else if (!Q_stricmp(token, "if"))
|
|
|
|
{
|
|
|
|
qboolean conditionistrue = Shader_EvaluateCondition(&shadersource);
|
|
|
|
|
|
|
|
while (shadersource)
|
|
|
|
{
|
|
|
|
token = COM_ParseExt (&shadersource, true);
|
|
|
|
if ( !token[0] )
|
|
|
|
continue;
|
|
|
|
else if (token[0] == ']')
|
|
|
|
break;
|
|
|
|
else if (conditionistrue)
|
|
|
|
{
|
|
|
|
if (token[0] == '{')
|
|
|
|
Shader_Readpass (s, &shadersource);
|
|
|
|
else
|
|
|
|
Shader_Parsetok (s, NULL, shaderkeys, token, &shadersource);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if ( token[0] == '{' )
|
|
|
|
Shader_Readpass ( s, &shadersource );
|
|
|
|
else if ( Shader_Parsetok (s, NULL, shaderkeys, token, &shadersource ) )
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
Shader_Finish ( s );
|
|
|
|
}
|
|
|
|
|
2010-07-11 02:22:39 +00:00
|
|
|
static qboolean Shader_ParseShader(char *shortname, char *usename, shader_t *s)
|
2006-03-11 03:12:10 +00:00
|
|
|
{
|
|
|
|
unsigned int offset = 0, length;
|
|
|
|
char path[MAX_QPATH];
|
|
|
|
char *buf = NULL, *ts = NULL;
|
|
|
|
|
|
|
|
Shader_GetPathAndOffset( shortname, &ts, &offset );
|
|
|
|
|
|
|
|
if ( ts )
|
|
|
|
{
|
|
|
|
Com_sprintf ( path, sizeof(path), "%s", ts );
|
|
|
|
length = FS_LoadFile ( path, (void **)&buf );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
length = 0;
|
|
|
|
|
|
|
|
// the shader is in the shader scripts
|
|
|
|
if ( ts && buf && (offset < length) )
|
|
|
|
{
|
|
|
|
char *file, *token;
|
|
|
|
|
|
|
|
|
|
|
|
file = buf + offset;
|
|
|
|
token = COM_ParseExt (&file, true);
|
|
|
|
if ( !file || token[0] != '{' )
|
|
|
|
{
|
|
|
|
FS_FreeFile(buf);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
Shader_Free(s);
|
2006-03-11 03:12:10 +00:00
|
|
|
memset ( s, 0, sizeof( shader_t ) );
|
|
|
|
Com_sprintf ( s->name, MAX_QPATH, usename );
|
2010-07-11 02:22:39 +00:00
|
|
|
Hash_Add(&shader_active_hash, s->name, s, &s->bucket);
|
2006-03-11 03:12:10 +00:00
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
Shader_ReadShader(s, file);
|
2006-03-11 03:12:10 +00:00
|
|
|
|
|
|
|
FS_FreeFile(buf);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (buf)
|
|
|
|
FS_FreeFile(buf);
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
2010-07-11 02:22:39 +00:00
|
|
|
void R_UnloadShader(shader_t *shader)
|
|
|
|
{
|
|
|
|
if (shader->uses-- == 1)
|
|
|
|
Shader_Free(shader);
|
|
|
|
}
|
|
|
|
static int R_LoadShader ( char *name, shader_gen_t *defaultgen, const char *genargs)
|
2004-10-19 15:56:22 +00:00
|
|
|
{
|
|
|
|
int i, f = -1;
|
2006-03-11 03:12:10 +00:00
|
|
|
char shortname[MAX_QPATH];
|
2004-10-19 15:56:22 +00:00
|
|
|
shader_t *s;
|
|
|
|
|
2006-03-11 03:12:10 +00:00
|
|
|
COM_StripExtension ( name, shortname, sizeof(shortname));
|
2004-10-19 15:56:22 +00:00
|
|
|
|
2005-08-26 22:56:51 +00:00
|
|
|
COM_CleanUpPath(shortname);
|
|
|
|
|
2010-07-11 02:22:39 +00:00
|
|
|
// check the hash first
|
|
|
|
s = Hash_Get(&shader_active_hash, shortname);
|
|
|
|
if (s)
|
|
|
|
{
|
|
|
|
i = s - r_shaders;
|
|
|
|
r_shaders[i].uses++;
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
// not loaded, find a free slot
|
2004-10-19 15:56:22 +00:00
|
|
|
for (i = 0; i < MAX_SHADERS; i++)
|
|
|
|
{
|
2010-07-11 02:22:39 +00:00
|
|
|
if (!r_shaders[i].uses)
|
2004-10-19 15:56:22 +00:00
|
|
|
{
|
|
|
|
if ( f == -1 ) // free shader
|
2010-07-11 02:22:39 +00:00
|
|
|
{
|
2004-10-19 15:56:22 +00:00
|
|
|
f = i;
|
2010-07-11 02:22:39 +00:00
|
|
|
break;
|
|
|
|
}
|
2004-10-19 15:56:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( f == -1 )
|
|
|
|
{
|
|
|
|
Sys_Error( "R_LoadShader: Shader limit exceeded.");
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
|
|
|
|
s = &r_shaders[f];
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
if (ruleset_allow_shaders.ival)
|
2004-10-19 15:56:22 +00:00
|
|
|
{
|
2009-11-04 21:16:50 +00:00
|
|
|
#ifdef GLQUAKE
|
|
|
|
if (qrenderer == QR_OPENGL && gl_config.arb_shader_objects)
|
|
|
|
{
|
|
|
|
if (Shader_ParseShader(va("%s_glsl", shortname), shortname, s))
|
|
|
|
{
|
|
|
|
s->generator = defaultgen;
|
|
|
|
s->genargs = genargs;
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
if (Shader_ParseShader(shortname, shortname, s))
|
|
|
|
{
|
|
|
|
s->generator = defaultgen;
|
|
|
|
s->genargs = genargs;
|
2006-03-11 03:12:10 +00:00
|
|
|
return f;
|
2009-11-04 21:16:50 +00:00
|
|
|
}
|
2006-03-11 03:12:10 +00:00
|
|
|
}
|
2004-10-19 15:56:22 +00:00
|
|
|
|
2006-03-11 03:12:10 +00:00
|
|
|
// make a default shader
|
2004-10-19 15:56:22 +00:00
|
|
|
|
2006-03-11 03:12:10 +00:00
|
|
|
if (defaultgen)
|
2004-10-19 15:56:22 +00:00
|
|
|
{
|
2006-03-11 03:12:10 +00:00
|
|
|
memset ( s, 0, sizeof( shader_t ) );
|
2009-11-04 21:16:50 +00:00
|
|
|
s->generator = defaultgen;
|
|
|
|
s->genargs = genargs;
|
2006-03-11 03:12:10 +00:00
|
|
|
Com_sprintf ( s->name, MAX_QPATH, shortname );
|
2010-07-11 02:22:39 +00:00
|
|
|
Hash_Add(&shader_active_hash, s->name, s, &s->bucket);
|
2009-06-21 17:45:33 +00:00
|
|
|
defaultgen(shortname, s, genargs);
|
2004-10-19 15:56:22 +00:00
|
|
|
|
2006-03-11 03:12:10 +00:00
|
|
|
return f;
|
|
|
|
}
|
|
|
|
return -1;
|
2004-10-19 15:56:22 +00:00
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
void Shader_DoReload(void)
|
|
|
|
{
|
|
|
|
shader_t *s;
|
|
|
|
unsigned int i;
|
|
|
|
char shortname[MAX_QPATH];
|
|
|
|
shader_gen_t *defaultgen;
|
|
|
|
const char *genargs;
|
|
|
|
texnums_t oldtn;
|
|
|
|
|
2010-07-11 02:22:39 +00:00
|
|
|
if (shader_rescan_needed && ruleset_allow_shaders.ival)
|
|
|
|
{
|
|
|
|
Con_Printf ( "Initializing Shaders.\n" );
|
|
|
|
|
|
|
|
COM_EnumerateFiles("shaders/*.shader", Shader_InitCallback, NULL);
|
|
|
|
COM_EnumerateFiles("scripts/*.shader", Shader_InitCallback, NULL);
|
|
|
|
//COM_EnumerateFiles("scripts/*.rscript", Shader_InitCallback, NULL);
|
|
|
|
|
|
|
|
shader_reload_needed = true;
|
|
|
|
shader_rescan_needed = false;
|
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
if (!shader_reload_needed)
|
|
|
|
return;
|
|
|
|
shader_reload_needed = false;
|
2010-03-14 14:35:56 +00:00
|
|
|
Font_InvalidateColour();
|
2009-11-04 21:16:50 +00:00
|
|
|
Con_Printf("Reloading all shaders\n");
|
|
|
|
|
|
|
|
for (s = r_shaders, i = 0; i < MAX_SHADERS; i++, s++)
|
|
|
|
{
|
2010-07-11 02:22:39 +00:00
|
|
|
if (!s->uses)
|
2009-11-04 21:16:50 +00:00
|
|
|
continue;
|
|
|
|
|
|
|
|
defaultgen = s->generator;
|
|
|
|
genargs = s->genargs;
|
|
|
|
oldtn = s->defaulttextures;
|
|
|
|
|
|
|
|
strcpy(shortname, s->name);
|
|
|
|
if (ruleset_allow_shaders.ival)
|
|
|
|
{
|
|
|
|
#ifdef GLQUAKE
|
|
|
|
if (qrenderer == QR_OPENGL && gl_config.arb_shader_objects)
|
|
|
|
{
|
|
|
|
if (Shader_ParseShader(va("%s_glsl", shortname), shortname, s))
|
|
|
|
{
|
|
|
|
s->generator = defaultgen;
|
|
|
|
s->genargs = genargs;
|
|
|
|
R_BuildDefaultTexnums(&oldtn, s);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
if (Shader_ParseShader(shortname, shortname, s))
|
|
|
|
{
|
|
|
|
s->generator = defaultgen;
|
|
|
|
s->genargs = genargs;
|
|
|
|
R_BuildDefaultTexnums(&oldtn, s);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (s->generator)
|
|
|
|
{
|
|
|
|
Shader_Free(s);
|
|
|
|
memset ( s, 0, sizeof( shader_t ) );
|
|
|
|
s->generator = defaultgen;
|
|
|
|
s->genargs = genargs;
|
|
|
|
Com_sprintf ( s->name, MAX_QPATH, shortname );
|
2010-07-11 02:22:39 +00:00
|
|
|
Hash_Add(&shader_active_hash, s->name, s, &s->bucket);
|
2009-11-04 21:16:50 +00:00
|
|
|
s->generator(shortname, s, s->genargs);
|
|
|
|
R_BuildDefaultTexnums(&oldtn, s);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Shader_NeedReload(void)
|
|
|
|
{
|
|
|
|
shader_reload_needed = true;
|
|
|
|
}
|
|
|
|
|
2010-07-11 02:22:39 +00:00
|
|
|
cin_t *R_ShaderGetCinematic(shader_t *s)
|
|
|
|
{
|
|
|
|
#ifndef NOMEDIA
|
|
|
|
int j;
|
|
|
|
if (!s)
|
|
|
|
return NULL;
|
|
|
|
for (j = 0; j < s->numpasses; j++)
|
|
|
|
if (s->passes[j].cin)
|
|
|
|
return s->passes[j].cin;
|
|
|
|
#endif
|
|
|
|
/*no cinematic in this shader!*/
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
cin_t *R_ShaderFindCinematic(char *name)
|
2008-11-09 22:29:28 +00:00
|
|
|
{
|
2009-11-04 21:16:50 +00:00
|
|
|
#ifdef NOMEDIA
|
|
|
|
return NULL;
|
|
|
|
#else
|
2010-07-11 02:22:39 +00:00
|
|
|
int i;
|
|
|
|
char shortname[MAX_QPATH];
|
2008-11-09 22:29:28 +00:00
|
|
|
|
|
|
|
COM_StripExtension ( name, shortname, sizeof(shortname));
|
|
|
|
|
|
|
|
COM_CleanUpPath(shortname);
|
|
|
|
|
|
|
|
//try and find it
|
|
|
|
for (i = 0; i < MAX_SHADERS; i++)
|
|
|
|
{
|
2010-07-11 02:22:39 +00:00
|
|
|
if (!r_shaders[i].uses)
|
2008-11-09 22:29:28 +00:00
|
|
|
continue;
|
|
|
|
|
|
|
|
if (!Q_stricmp (shortname, r_shaders[i].name) )
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (i == MAX_SHADERS)
|
|
|
|
return NULL;
|
|
|
|
|
2010-07-11 02:22:39 +00:00
|
|
|
//found the named shader.
|
|
|
|
return R_ShaderGetCinematic(&r_shaders[i]);
|
2009-11-04 21:16:50 +00:00
|
|
|
#endif
|
2008-11-09 22:29:28 +00:00
|
|
|
}
|
|
|
|
|
2004-10-19 15:56:22 +00:00
|
|
|
shader_t *R_RegisterPic (char *name)
|
|
|
|
{
|
2009-06-21 17:45:33 +00:00
|
|
|
return &r_shaders[R_LoadShader (name, Shader_Default2D, NULL)];
|
2004-10-19 15:56:22 +00:00
|
|
|
}
|
|
|
|
|
2009-11-04 21:16:50 +00:00
|
|
|
shader_t *R_RegisterShader (char *name, const char *shaderscript)
|
|
|
|
{
|
|
|
|
return &r_shaders[R_LoadShader (name, Shader_DefaultScript, shaderscript)];
|
|
|
|
}
|
|
|
|
|
|
|
|
shader_t *R_RegisterShader_Lightmap (char *name)
|
2004-10-19 15:56:22 +00:00
|
|
|
{
|
2010-07-11 02:22:39 +00:00
|
|
|
return &r_shaders[R_LoadShader (name, Shader_DefaultBSPLM, NULL)];
|
2004-10-19 15:56:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
shader_t *R_RegisterShader_Vertex (char *name)
|
|
|
|
{
|
2009-06-21 17:45:33 +00:00
|
|
|
return &r_shaders[R_LoadShader (name, Shader_DefaultBSPVertex, NULL)];
|
2004-10-19 15:56:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
shader_t *R_RegisterShader_Flare (char *name)
|
|
|
|
{
|
2009-06-21 17:45:33 +00:00
|
|
|
return &r_shaders[R_LoadShader (name, Shader_DefaultBSPFlare, NULL)];
|
2004-10-19 15:56:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
shader_t *R_RegisterSkin (char *name)
|
|
|
|
{
|
2009-06-21 17:45:33 +00:00
|
|
|
return &r_shaders[R_LoadShader (name, Shader_DefaultSkin, NULL)];
|
2005-03-20 02:57:11 +00:00
|
|
|
}
|
2009-11-04 21:16:50 +00:00
|
|
|
shader_t *R_RegisterCustom (char *name, shader_gen_t *defaultgen, const void *args)
|
2005-03-20 02:57:11 +00:00
|
|
|
{
|
2005-08-03 23:14:59 +00:00
|
|
|
int i;
|
2009-06-21 17:45:33 +00:00
|
|
|
i = R_LoadShader (name, defaultgen, args);
|
2005-08-03 23:14:59 +00:00
|
|
|
if (i < 0)
|
|
|
|
return NULL;
|
|
|
|
return &r_shaders[i];
|
2004-10-19 15:56:22 +00:00
|
|
|
}
|
2009-11-04 21:16:50 +00:00
|
|
|
#endif //SERVERONLY
|