User friendlier shader error handling
Loading cubemaps from shaders (for light shaders)
This commit is contained in:
parent
487b36662a
commit
e9cbe091a3
1 changed files with 65 additions and 19 deletions
82
shaders.c
82
shaders.c
|
@ -35,7 +35,10 @@ static shader_t *shaderList;
|
||||||
|
|
||||||
void GL_ShaderLoadTextures(shader_t *shader);
|
void GL_ShaderLoadTextures(shader_t *shader);
|
||||||
|
|
||||||
|
qboolean shader_haserrors;
|
||||||
|
|
||||||
void ShaderError(void) {
|
void ShaderError(void) {
|
||||||
|
shader_haserrors = true;
|
||||||
if ( !COM_CheckParm ("-forceshaders") )
|
if ( !COM_CheckParm ("-forceshaders") )
|
||||||
Con_NotifyBox("Shader error\nSee above for details\n");
|
Con_NotifyBox("Shader error\nSee above for details\n");
|
||||||
}
|
}
|
||||||
|
@ -47,6 +50,7 @@ void ShaderError(void) {
|
||||||
void clearStage(stage_t *stage) {
|
void clearStage(stage_t *stage) {
|
||||||
memset(stage,0,sizeof(stage_t));
|
memset(stage,0,sizeof(stage_t));
|
||||||
stage->texture[0] = NULL;
|
stage->texture[0] = NULL;
|
||||||
|
stage->alphatresh = 0;
|
||||||
stage->type = STAGE_SIMPLE;
|
stage->type = STAGE_SIMPLE;
|
||||||
stage->src_blend = -1;
|
stage->src_blend = -1;
|
||||||
stage->dst_blend = -1;
|
stage->dst_blend = -1;
|
||||||
|
@ -88,6 +92,16 @@ void initDefaultShader(char *name, shader_t *shader) {
|
||||||
shader->flags |= (SURF_GLOSS | SURF_PPLIGHT | SURF_BUMP);
|
shader->flags |= (SURF_GLOSS | SURF_PPLIGHT | SURF_BUMP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void initErrorShader(shader_t *shader) {
|
||||||
|
shader->numbumpstages = 0;
|
||||||
|
shader->numcolorstages = 0;
|
||||||
|
shader->numglossstages = 0;
|
||||||
|
shader->flags = 0;
|
||||||
|
shader->cull = true;
|
||||||
|
shader->mipmap = true;
|
||||||
|
shader->numstages = 1;
|
||||||
|
initDefaultStage("textures/system/shadererror.tga", &shader->stages[0], STAGE_SIMPLE);
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
================
|
================
|
||||||
GL_ShaderForName
|
GL_ShaderForName
|
||||||
|
@ -137,9 +151,14 @@ void StageLoadTextures(stage_t *stage, shader_t *shader) {
|
||||||
switch (stage->type) {
|
switch (stage->type) {
|
||||||
case STAGE_COLOR:
|
case STAGE_COLOR:
|
||||||
case STAGE_GLOSS:
|
case STAGE_GLOSS:
|
||||||
case STAGE_SIMPLE:
|
|
||||||
stage->texture[0] = GL_CacheTexture(stage->filename, shader->mipmap, TEXTURE_RGB);
|
stage->texture[0] = GL_CacheTexture(stage->filename, shader->mipmap, TEXTURE_RGB);
|
||||||
break;
|
break;
|
||||||
|
case STAGE_SIMPLE:
|
||||||
|
if (stage->flags & STAGE_CUBEMAP)
|
||||||
|
stage->texture[0] = GL_CacheTexture(stage->filename, shader->mipmap, TEXTURE_CUBEMAP);
|
||||||
|
else
|
||||||
|
stage->texture[0] = GL_CacheTexture(stage->filename, shader->mipmap, TEXTURE_RGB);
|
||||||
|
break;
|
||||||
case STAGE_BUMP:
|
case STAGE_BUMP:
|
||||||
stage->texture[0] = GL_CacheTexture(stage->filename, shader->mipmap, TEXTURE_NORMAL);
|
stage->texture[0] = GL_CacheTexture(stage->filename, shader->mipmap, TEXTURE_NORMAL);
|
||||||
break;
|
break;
|
||||||
|
@ -199,10 +218,15 @@ qboolean IsShaderBlended(shader_t *s) {
|
||||||
|
|
||||||
// parse some stuff but make sure you give some errors
|
// parse some stuff but make sure you give some errors
|
||||||
#define GET_SAFE_TOKEN data = COM_Parse (data);\
|
#define GET_SAFE_TOKEN data = COM_Parse (data);\
|
||||||
if (!data)\
|
if (!data) {\
|
||||||
Sys_Error ("ED_ParseEntity: EOF without closing brace");\
|
Con_Printf ("LoadShader: EOF without closing brace");\
|
||||||
if (com_token[0] == '}')\
|
ShaderError();\
|
||||||
Sys_Error ("ED_ParseEntity: '}' not expected here")
|
}\
|
||||||
|
if (com_token[0] == '}') {\
|
||||||
|
Sys_Error ("LoadShader: '}' not expected here");\
|
||||||
|
ShaderError();\
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse a tcmod command out of the shader file
|
* Parse a tcmod command out of the shader file
|
||||||
|
@ -283,10 +307,11 @@ char *ParseStage (char *data, shader_t *shader)
|
||||||
char command[MAX_QPATH];
|
char command[MAX_QPATH];
|
||||||
char texture[MAX_QPATH*3+2], detail[MAX_QPATH];
|
char texture[MAX_QPATH*3+2], detail[MAX_QPATH];
|
||||||
stage_t stage;
|
stage_t stage;
|
||||||
qboolean isgraygloss;
|
qboolean isgraygloss, hascubetexture;
|
||||||
//Con_Printf("Parsing shader stage...\n");
|
//Con_Printf("Parsing shader stage...\n");
|
||||||
clearStage(&stage);
|
clearStage(&stage);
|
||||||
isgraygloss = false;
|
isgraygloss = false;
|
||||||
|
hascubetexture = false;
|
||||||
|
|
||||||
// go through all the dictionary pairs
|
// go through all the dictionary pairs
|
||||||
while (1)
|
while (1)
|
||||||
|
@ -336,9 +361,13 @@ char *ParseStage (char *data, shader_t *shader)
|
||||||
shader->bumpstages[shader->numbumpstages] = stage;
|
shader->bumpstages[shader->numbumpstages] = stage;
|
||||||
shader->numbumpstages++;
|
shader->numbumpstages++;
|
||||||
|
|
||||||
} else {
|
} else { //Default stage
|
||||||
if (shader->numstages >= SHADER_MAX_STAGES)
|
if (shader->numstages >= SHADER_MAX_STAGES)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
if (hascubetexture)
|
||||||
|
stage.flags = stage.flags | STAGE_CUBEMAP;
|
||||||
|
|
||||||
shader->stages[shader->numstages] = stage;
|
shader->stages[shader->numstages] = stage;
|
||||||
shader->numstages++;
|
shader->numstages++;
|
||||||
}
|
}
|
||||||
|
@ -346,8 +375,11 @@ char *ParseStage (char *data, shader_t *shader)
|
||||||
}
|
}
|
||||||
|
|
||||||
//ugh nasty
|
//ugh nasty
|
||||||
if (!data)
|
if (!data) {
|
||||||
Sys_Error ("ParseStage: EOF without '}'");
|
Con_Printf("ParseStage: EOF without '}'");
|
||||||
|
ShaderError();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
//see what command it is
|
//see what command it is
|
||||||
strncpy (command, com_token,sizeof(command));
|
strncpy (command, com_token,sizeof(command));
|
||||||
|
@ -380,6 +412,11 @@ char *ParseStage (char *data, shader_t *shader)
|
||||||
strncpy(detail, com_token, MAX_QPATH);
|
strncpy(detail, com_token, MAX_QPATH);
|
||||||
GET_SAFE_TOKEN;
|
GET_SAFE_TOKEN;
|
||||||
sprintf(texture, "%s+%s", detail, com_token);
|
sprintf(texture, "%s+%s", detail, com_token);
|
||||||
|
} else if (!strcmp(com_token, "cube")) {
|
||||||
|
//It's a cube map
|
||||||
|
GET_SAFE_TOKEN;
|
||||||
|
strncpy(texture,com_token, MAX_QPATH);
|
||||||
|
hascubetexture = true;
|
||||||
} else
|
} else
|
||||||
strncpy(texture,com_token,MAX_QPATH);
|
strncpy(texture,com_token,MAX_QPATH);
|
||||||
|
|
||||||
|
@ -545,8 +582,11 @@ char *ParseShader (char *data, shader_t *shader)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//ugh nasty
|
//ugh nasty
|
||||||
if (!data)
|
if (!data) {
|
||||||
Sys_Error ("ParseShader: EOF without '}'");
|
Con_Printf("ParseStage: EOF without '}'");
|
||||||
|
ShaderError();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
//see what command it is
|
//see what command it is
|
||||||
strncpy (command, com_token,sizeof(command));
|
strncpy (command, com_token,sizeof(command));
|
||||||
|
@ -602,6 +642,9 @@ void LoadShadersFromString (char *data,const char *filename)
|
||||||
if (!data)
|
if (!data)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
//No errors yet.
|
||||||
|
shader_haserrors = false;
|
||||||
|
|
||||||
//check if shader already exists
|
//check if shader already exists
|
||||||
s = shaderList;
|
s = shaderList;
|
||||||
while(s) {
|
while(s) {
|
||||||
|
@ -609,7 +652,7 @@ void LoadShadersFromString (char *data,const char *filename)
|
||||||
Con_Printf("Shader error:\nShader '%s' was defined a second time in '%s'\n",com_token, filename);
|
Con_Printf("Shader error:\nShader '%s' was defined a second time in '%s'\n",com_token, filename);
|
||||||
Con_Printf("This may cause texture errors\n");
|
Con_Printf("This may cause texture errors\n");
|
||||||
ShaderError();
|
ShaderError();
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
s = s->next;
|
s = s->next;
|
||||||
}
|
}
|
||||||
|
@ -628,15 +671,18 @@ void LoadShadersFromString (char *data,const char *filename)
|
||||||
data = COM_Parse (data);
|
data = COM_Parse (data);
|
||||||
if (!data)
|
if (!data)
|
||||||
break;
|
break;
|
||||||
if (com_token[0] != '{')
|
if (com_token[0] != '{') {
|
||||||
Sys_Error ("ED_LoadFromFile: found %s when expecting {",com_token);
|
Con_Printf("ED_LoadFromFile: found %s when expecting {",com_token);
|
||||||
|
ShaderError();
|
||||||
|
}
|
||||||
|
|
||||||
//Con_Printf("Parsing %s...\n",s->name);
|
Con_DPrintf("Parsing %s...\n",s->name);
|
||||||
data = ParseShader (data, s);
|
data = ParseShader (data, s);
|
||||||
}
|
|
||||||
|
|
||||||
if ((!fog_start.value) && (!fog_end.value)) {
|
if (shader_haserrors) {
|
||||||
Cvar_SetValue ("gl_fog",0.0);
|
Con_Printf("setuperror\n");
|
||||||
|
initErrorShader(s);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue