]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - model_brush.c
centered quake hud in deathmatch, this makes the new score block visible
[xonotic/darkplaces.git] / model_brush.c
index 1f0eff6123dc7b937f69a896d650c3ddc19a3003..ad1d484c4a658040589c6fbef82e4788f06f4fce 100644 (file)
@@ -1381,7 +1381,10 @@ static void Mod_Q1BSP_LoadTextures(lump_t *l)
        }
 
        if (!m)
+       {
+               Con_Printf("%s: no miptex lump to load textures from\n", loadmodel->name);
                return;
+       }
 
        s = loadmodel->name;
        if (!strncasecmp(s, "maps/", 5))
@@ -1394,15 +1397,28 @@ static void Mod_Q1BSP_LoadTextures(lump_t *l)
        for (i = 0;i < m->nummiptex;i++)
        {
                dofs[i] = LittleLong(dofs[i]);
-               if (dofs[i] == -1 || r_nosurftextures.integer)
+               if (r_nosurftextures.integer)
                        continue;
+               if (dofs[i] == -1)
+               {
+                       Con_DPrintf("%s: miptex #%i missing\n", loadmodel->name, i);
+                       continue;
+               }
                dmiptex = (miptex_t *)((unsigned char *)m + dofs[i]);
 
-               // make sure name is no more than 15 characters
-               for (j = 0;dmiptex->name[j] && j < 15;j++)
+               // copy name, but only up to 16 characters
+               // (the output buffer can hold more than this, but the input buffer is
+               //  only 16)
+               for (j = 0;dmiptex->name[j] && j < 16;j++)
                        name[j] = dmiptex->name[j];
                name[j] = 0;
 
+               if (!name[0])
+               {
+                       sprintf(name, "unnamed%i", i);
+                       Con_DPrintf("%s: warning: renaming unnamed texture to %s\n", loadmodel->name, name);
+               }
+
                mtwidth = LittleLong(dmiptex->width);
                mtheight = LittleLong(dmiptex->height);
                mtdata = NULL;
@@ -1412,31 +1428,28 @@ static void Mod_Q1BSP_LoadTextures(lump_t *l)
                        // texture included
                        if (j < 40 || j + mtwidth * mtheight > l->filelen)
                        {
-                               Con_Printf("Texture \"%s\" in \"%s\"is corrupt or incomplete\n", dmiptex->name, loadmodel->name);
+                               Con_Printf("%s: Texture \"%s\" is corrupt or incomplete\n", loadmodel->name, dmiptex->name);
                                continue;
                        }
                        mtdata = (unsigned char *)dmiptex + j;
                }
 
                if ((mtwidth & 15) || (mtheight & 15))
-                       Con_Printf("warning: texture \"%s\" in \"%s\" is not 16 aligned\n", dmiptex->name, loadmodel->name);
+                       Con_DPrintf("%s: warning: texture \"%s\" is not 16 aligned\n", loadmodel->name, dmiptex->name);
 
                // LordHavoc: force all names to lowercase
                for (j = 0;name[j];j++)
                        if (name[j] >= 'A' && name[j] <= 'Z')
                                name[j] += 'a' - 'A';
 
+               if (dmiptex->name[0] && Mod_LoadTextureFromQ3Shader(loadmodel->data_textures + i, name, true, false, false))
+                       continue;
+
                tx = loadmodel->data_textures + i;
                strlcpy(tx->name, name, sizeof(tx->name));
                tx->width = mtwidth;
                tx->height = mtheight;
 
-               if (!tx->name[0])
-               {
-                       sprintf(tx->name, "unnamed%i", i);
-                       Con_Printf("warning: unnamed texture in %s, renaming to %s\n", loadmodel->name, tx->name);
-               }
-
                if (tx->name[0] == '*')
                {
                        if (!strncmp(tx->name, "*lava", 5))
@@ -4096,368 +4109,6 @@ static void Mod_Q3BSP_LoadEntities(lump_t *l)
        }
 }
 
-// FIXME: make MAXSHADERS dynamic
-#define Q3SHADER_MAXSHADERS 4096
-#define Q3SHADER_MAXLAYERS 8
-
-typedef struct q3shaderinfo_layer_s
-{
-       int alphatest;
-       int clampmap;
-       float framerate;
-       int numframes;
-       char texturename[TEXTURE_MAXFRAMES][Q3PATHLENGTH];
-       int blendfunc[2];
-       qboolean rgbgenvertex;
-       qboolean alphagenvertex;
-}
-q3shaderinfo_layer_t;
-
-typedef struct q3shaderinfo_s
-{
-       char name[Q3PATHLENGTH];
-       int surfaceparms;
-       int textureflags;
-       int numlayers;
-       qboolean lighting;
-       qboolean vertexalpha;
-       qboolean textureblendalpha;
-       q3shaderinfo_layer_t *primarylayer, *backgroundlayer;
-       q3shaderinfo_layer_t layers[Q3SHADER_MAXLAYERS];
-       char skyboxname[Q3PATHLENGTH];
-}
-q3shaderinfo_t;
-
-int q3shaders_numshaders;
-q3shaderinfo_t q3shaders_shaders[Q3SHADER_MAXSHADERS];
-
-static void Mod_Q3BSP_LoadShaders(void)
-{
-       int j;
-       int fileindex;
-       fssearch_t *search;
-       char *f;
-       const char *text;
-       q3shaderinfo_t *shader;
-       q3shaderinfo_layer_t *layer;
-       int numparameters;
-       char parameter[TEXTURE_MAXFRAMES + 4][Q3PATHLENGTH];
-       search = FS_Search("scripts/*.shader", true, false);
-       if (!search)
-               return;
-       q3shaders_numshaders = 0;
-       for (fileindex = 0;fileindex < search->numfilenames;fileindex++)
-       {
-               text = f = (char *)FS_LoadFile(search->filenames[fileindex], tempmempool, false, NULL);
-               if (!f)
-                       continue;
-               while (COM_ParseToken_QuakeC(&text, false))
-               {
-                       if (q3shaders_numshaders >= Q3SHADER_MAXSHADERS)
-                       {
-                               Con_Printf("Mod_Q3BSP_LoadShaders: too many shaders!\n");
-                               break;
-                       }
-                       shader = q3shaders_shaders + q3shaders_numshaders++;
-                       memset(shader, 0, sizeof(*shader));
-                       strlcpy(shader->name, com_token, sizeof(shader->name));
-                       if (!COM_ParseToken_QuakeC(&text, false) || strcasecmp(com_token, "{"))
-                       {
-                               Con_Printf("%s parsing error - expected \"{\", found \"%s\"\n", search->filenames[fileindex], com_token);
-                               break;
-                       }
-                       while (COM_ParseToken_QuakeC(&text, false))
-                       {
-                               if (!strcasecmp(com_token, "}"))
-                                       break;
-                               if (!strcasecmp(com_token, "{"))
-                               {
-                                       if (shader->numlayers < Q3SHADER_MAXLAYERS)
-                                       {
-                                               layer = shader->layers + shader->numlayers++;
-                                               layer->rgbgenvertex = false;
-                                               layer->alphagenvertex = false;
-                                               layer->blendfunc[0] = GL_ONE;
-                                               layer->blendfunc[1] = GL_ZERO;
-                                       }
-                                       else
-                                               layer = NULL;
-                                       while (COM_ParseToken_QuakeC(&text, false))
-                                       {
-                                               if (!strcasecmp(com_token, "}"))
-                                                       break;
-                                               if (!strcasecmp(com_token, "\n"))
-                                                       continue;
-                                               if (layer == NULL)
-                                                       continue;
-                                               numparameters = 0;
-                                               for (j = 0;strcasecmp(com_token, "\n") && strcasecmp(com_token, "}");j++)
-                                               {
-                                                       if (j < TEXTURE_MAXFRAMES + 4)
-                                                       {
-                                                               strlcpy(parameter[j], com_token, sizeof(parameter[j]));
-                                                               numparameters = j + 1;
-                                                       }
-                                                       if (!COM_ParseToken_QuakeC(&text, true))
-                                                               break;
-                                               }
-                                               if (developer.integer >= 100)
-                                               {
-                                                       Con_Printf("%s %i: ", shader->name, shader->numlayers - 1);
-                                                       for (j = 0;j < numparameters;j++)
-                                                               Con_Printf(" %s", parameter[j]);
-                                                       Con_Print("\n");
-                                               }
-                                               if (numparameters >= 2 && !strcasecmp(parameter[0], "blendfunc"))
-                                               {
-                                                       if (numparameters == 2)
-                                                       {
-                                                               if (!strcasecmp(parameter[1], "add"))
-                                                               {
-                                                                       layer->blendfunc[0] = GL_ONE;
-                                                                       layer->blendfunc[1] = GL_ONE;
-                                                               }
-                                                               else if (!strcasecmp(parameter[1], "filter"))
-                                                               {
-                                                                       layer->blendfunc[0] = GL_DST_COLOR;
-                                                                       layer->blendfunc[1] = GL_ZERO;
-                                                               }
-                                                               else if (!strcasecmp(parameter[1], "blend"))
-                                                               {
-                                                                       layer->blendfunc[0] = GL_SRC_ALPHA;
-                                                                       layer->blendfunc[1] = GL_ONE_MINUS_SRC_ALPHA;
-                                                               }
-                                                       }
-                                                       else if (numparameters == 3)
-                                                       {
-                                                               int k;
-                                                               for (k = 0;k < 2;k++)
-                                                               {
-                                                                       if (!strcasecmp(parameter[k+1], "GL_ONE"))
-                                                                               layer->blendfunc[k] = GL_ONE;
-                                                                       else if (!strcasecmp(parameter[k+1], "GL_ZERO"))
-                                                                               layer->blendfunc[k] = GL_ZERO;
-                                                                       else if (!strcasecmp(parameter[k+1], "GL_SRC_COLOR"))
-                                                                               layer->blendfunc[k] = GL_SRC_COLOR;
-                                                                       else if (!strcasecmp(parameter[k+1], "GL_SRC_ALPHA"))
-                                                                               layer->blendfunc[k] = GL_SRC_ALPHA;
-                                                                       else if (!strcasecmp(parameter[k+1], "GL_DST_COLOR"))
-                                                                               layer->blendfunc[k] = GL_DST_COLOR;
-                                                                       else if (!strcasecmp(parameter[k+1], "GL_DST_ALPHA"))
-                                                                               layer->blendfunc[k] = GL_ONE_MINUS_DST_ALPHA;
-                                                                       else if (!strcasecmp(parameter[k+1], "GL_ONE_MINUS_SRC_COLOR"))
-                                                                               layer->blendfunc[k] = GL_ONE_MINUS_SRC_COLOR;
-                                                                       else if (!strcasecmp(parameter[k+1], "GL_ONE_MINUS_SRC_ALPHA"))
-                                                                               layer->blendfunc[k] = GL_ONE_MINUS_SRC_ALPHA;
-                                                                       else if (!strcasecmp(parameter[k+1], "GL_ONE_MINUS_DST_COLOR"))
-                                                                               layer->blendfunc[k] = GL_ONE_MINUS_DST_COLOR;
-                                                                       else if (!strcasecmp(parameter[k+1], "GL_ONE_MINUS_DST_ALPHA"))
-                                                                               layer->blendfunc[k] = GL_ONE_MINUS_DST_ALPHA;
-                                                                       else
-                                                                               layer->blendfunc[k] = GL_ONE; // default in case of parsing error
-                                                               }
-                                                       }
-                                               }
-                                               if (numparameters >= 2 && !strcasecmp(parameter[0], "alphafunc"))
-                                                       layer->alphatest = true;
-                                               if (numparameters >= 2 && (!strcasecmp(parameter[0], "map") || !strcasecmp(parameter[0], "clampmap")))
-                                               {
-                                                       if (!strcasecmp(parameter[0], "clampmap"))
-                                                               layer->clampmap = true;
-                                                       layer->numframes = 1;
-                                                       layer->framerate = 1;
-                                                       strlcpy(layer->texturename[0], parameter[1], sizeof(layer->texturename));
-                                                       if (!strcasecmp(parameter[1], "$lightmap"))
-                                                               shader->lighting = true;
-                                               }
-                                               else if (numparameters >= 3 && (!strcasecmp(parameter[0], "animmap") || !strcasecmp(parameter[0], "animclampmap")))
-                                               {
-                                                       int i;
-                                                       layer->numframes = min(numparameters - 2, TEXTURE_MAXFRAMES);
-                                                       layer->framerate = atof(parameter[1]);
-                                                       for (i = 0;i < layer->numframes;i++)
-                                                               strlcpy(layer->texturename[i], parameter[i + 2], sizeof(layer->texturename));
-                                               }
-                                               else if (numparameters >= 2 && !strcasecmp(parameter[0], "rgbgen") && !strcasecmp(parameter[1], "vertex"))
-                                                       layer->rgbgenvertex = true;
-                                               else if (numparameters >= 2 && !strcasecmp(parameter[0], "alphagen") && !strcasecmp(parameter[1], "vertex"))
-                                                       layer->alphagenvertex = true;
-                                               // break out a level if it was }
-                                               if (!strcasecmp(com_token, "}"))
-                                                       break;
-                                       }
-                                       if (layer->rgbgenvertex)
-                                               shader->lighting = true;
-                                       if (layer->alphagenvertex)
-                                       {
-                                               if (layer == shader->layers + 0)
-                                               {
-                                                       // vertex controlled transparency
-                                                       shader->vertexalpha = true;
-                                               }
-                                               else
-                                               {
-                                                       // multilayer terrain shader or similar
-                                                       shader->textureblendalpha = true;
-                                               }
-                                       }
-                                       continue;
-                               }
-                               numparameters = 0;
-                               for (j = 0;strcasecmp(com_token, "\n") && strcasecmp(com_token, "}");j++)
-                               {
-                                       if (j < TEXTURE_MAXFRAMES + 4)
-                                       {
-                                               strlcpy(parameter[j], com_token, sizeof(parameter[j]));
-                                               numparameters = j + 1;
-                                       }
-                                       if (!COM_ParseToken_QuakeC(&text, true))
-                                               break;
-                               }
-                               if (fileindex == 0 && !strcasecmp(com_token, "}"))
-                                       break;
-                               if (developer.integer >= 100)
-                               {
-                                       Con_Printf("%s: ", shader->name);
-                                       for (j = 0;j < numparameters;j++)
-                                               Con_Printf(" %s", parameter[j]);
-                                       Con_Print("\n");
-                               }
-                               if (numparameters < 1)
-                                       continue;
-                               if (!strcasecmp(parameter[0], "surfaceparm") && numparameters >= 2)
-                               {
-                                       if (!strcasecmp(parameter[1], "alphashadow"))
-                                               shader->surfaceparms |= Q3SURFACEPARM_ALPHASHADOW;
-                                       else if (!strcasecmp(parameter[1], "areaportal"))
-                                               shader->surfaceparms |= Q3SURFACEPARM_AREAPORTAL;
-                                       else if (!strcasecmp(parameter[1], "botclip"))
-                                               shader->surfaceparms |= Q3SURFACEPARM_BOTCLIP;
-                                       else if (!strcasecmp(parameter[1], "clusterportal"))
-                                               shader->surfaceparms |= Q3SURFACEPARM_CLUSTERPORTAL;
-                                       else if (!strcasecmp(parameter[1], "detail"))
-                                               shader->surfaceparms |= Q3SURFACEPARM_DETAIL;
-                                       else if (!strcasecmp(parameter[1], "donotenter"))
-                                               shader->surfaceparms |= Q3SURFACEPARM_DONOTENTER;
-                                       else if (!strcasecmp(parameter[1], "dust"))
-                                               shader->surfaceparms |= Q3SURFACEPARM_DUST;
-                                       else if (!strcasecmp(parameter[1], "hint"))
-                                               shader->surfaceparms |= Q3SURFACEPARM_HINT;
-                                       else if (!strcasecmp(parameter[1], "fog"))
-                                               shader->surfaceparms |= Q3SURFACEPARM_FOG;
-                                       else if (!strcasecmp(parameter[1], "lava"))
-                                               shader->surfaceparms |= Q3SURFACEPARM_LAVA;
-                                       else if (!strcasecmp(parameter[1], "lightfilter"))
-                                               shader->surfaceparms |= Q3SURFACEPARM_LIGHTFILTER;
-                                       else if (!strcasecmp(parameter[1], "lightgrid"))
-                                               shader->surfaceparms |= Q3SURFACEPARM_LIGHTGRID;
-                                       else if (!strcasecmp(parameter[1], "metalsteps"))
-                                               shader->surfaceparms |= Q3SURFACEPARM_METALSTEPS;
-                                       else if (!strcasecmp(parameter[1], "nodamage"))
-                                               shader->surfaceparms |= Q3SURFACEPARM_NODAMAGE;
-                                       else if (!strcasecmp(parameter[1], "nodlight"))
-                                               shader->surfaceparms |= Q3SURFACEPARM_NODLIGHT;
-                                       else if (!strcasecmp(parameter[1], "nodraw"))
-                                               shader->surfaceparms |= Q3SURFACEPARM_NODRAW;
-                                       else if (!strcasecmp(parameter[1], "nodrop"))
-                                               shader->surfaceparms |= Q3SURFACEPARM_NODROP;
-                                       else if (!strcasecmp(parameter[1], "noimpact"))
-                                               shader->surfaceparms |= Q3SURFACEPARM_NOIMPACT;
-                                       else if (!strcasecmp(parameter[1], "nolightmap"))
-                                               shader->surfaceparms |= Q3SURFACEPARM_NOLIGHTMAP;
-                                       else if (!strcasecmp(parameter[1], "nomarks"))
-                                               shader->surfaceparms |= Q3SURFACEPARM_NOMARKS;
-                                       else if (!strcasecmp(parameter[1], "nomipmaps"))
-                                               shader->surfaceparms |= Q3SURFACEPARM_NOMIPMAPS;
-                                       else if (!strcasecmp(parameter[1], "nonsolid"))
-                                               shader->surfaceparms |= Q3SURFACEPARM_NONSOLID;
-                                       else if (!strcasecmp(parameter[1], "origin"))
-                                               shader->surfaceparms |= Q3SURFACEPARM_ORIGIN;
-                                       else if (!strcasecmp(parameter[1], "playerclip"))
-                                               shader->surfaceparms |= Q3SURFACEPARM_PLAYERCLIP;
-                                       else if (!strcasecmp(parameter[1], "sky"))
-                                               shader->surfaceparms |= Q3SURFACEPARM_SKY;
-                                       else if (!strcasecmp(parameter[1], "slick"))
-                                               shader->surfaceparms |= Q3SURFACEPARM_SLICK;
-                                       else if (!strcasecmp(parameter[1], "slime"))
-                                               shader->surfaceparms |= Q3SURFACEPARM_SLIME;
-                                       else if (!strcasecmp(parameter[1], "structural"))
-                                               shader->surfaceparms |= Q3SURFACEPARM_STRUCTURAL;
-                                       else if (!strcasecmp(parameter[1], "trans"))
-                                               shader->surfaceparms |= Q3SURFACEPARM_TRANS;
-                                       else if (!strcasecmp(parameter[1], "water"))
-                                               shader->surfaceparms |= Q3SURFACEPARM_WATER;
-                                       else if (!strcasecmp(parameter[1], "pointlight"))
-                                               shader->surfaceparms |= Q3SURFACEPARM_POINTLIGHT;
-                                       else if (!strcasecmp(parameter[1], "antiportal"))
-                                               shader->surfaceparms |= Q3SURFACEPARM_ANTIPORTAL;
-                                       else
-                                               Con_DPrintf("%s parsing warning: unknown surfaceparm \"%s\"\n", search->filenames[fileindex], parameter[1]);
-                               }
-                               else if (!strcasecmp(parameter[0], "sky") && numparameters >= 2)
-                               {
-                                       // some q3 skies don't have the sky parm set
-                                       shader->surfaceparms |= Q3SURFACEPARM_SKY;
-                                       strlcpy(shader->skyboxname, parameter[1], sizeof(shader->skyboxname));
-                               }
-                               else if (!strcasecmp(parameter[0], "skyparms") && numparameters >= 2)
-                               {
-                                       // some q3 skies don't have the sky parm set
-                                       shader->surfaceparms |= Q3SURFACEPARM_SKY;
-                                       if (!atoi(parameter[1]) && strcasecmp(parameter[1], "-"))
-                                               strlcpy(shader->skyboxname, parameter[1], sizeof(shader->skyboxname));
-                               }
-                               else if (!strcasecmp(parameter[0], "cull") && numparameters >= 2)
-                               {
-                                       if (!strcasecmp(parameter[1], "disable") || !strcasecmp(parameter[1], "none") || !strcasecmp(parameter[1], "twosided"))
-                                               shader->textureflags |= Q3TEXTUREFLAG_TWOSIDED;
-                               }
-                               else if (!strcasecmp(parameter[0], "nomipmaps"))
-                                       shader->surfaceparms |= Q3SURFACEPARM_NOMIPMAPS;
-                               else if (!strcasecmp(parameter[0], "nopicmip"))
-                                       shader->textureflags |= Q3TEXTUREFLAG_NOPICMIP;
-                               else if (!strcasecmp(parameter[0], "deformvertexes") && numparameters >= 2)
-                               {
-                                       if (!strcasecmp(parameter[1], "autosprite") && numparameters == 2)
-                                               shader->textureflags |= Q3TEXTUREFLAG_AUTOSPRITE;
-                                       if (!strcasecmp(parameter[1], "autosprite2") && numparameters == 2)
-                                               shader->textureflags |= Q3TEXTUREFLAG_AUTOSPRITE2;
-                               }
-                       }
-                       // identify if this is a blended terrain shader or similar
-                       if (shader->numlayers)
-                       {
-                               shader->backgroundlayer = NULL;
-                               shader->primarylayer = shader->layers + 0;
-                               if ((shader->layers[0].blendfunc[0] == GL_ONE       && shader->layers[0].blendfunc[1] == GL_ZERO                && !shader->layers[0].alphatest)
-                               && ((shader->layers[1].blendfunc[0] == GL_SRC_ALPHA && shader->layers[1].blendfunc[1] == GL_ONE_MINUS_SRC_ALPHA && !shader->layers[0].alphatest)
-                               ||  (shader->layers[1].blendfunc[0] == GL_ONE       && shader->layers[1].blendfunc[1] == GL_ZERO                &&  shader->layers[1].alphatest)))
-                               {
-                                       // terrain blending or other effects
-                                       shader->backgroundlayer = shader->layers + 0;
-                                       shader->primarylayer = shader->layers + 1;
-                               }
-                               // now see if the lightmap came first, and if so choose the second texture instead
-                               if (!strcasecmp(shader->primarylayer->texturename[0], "$lightmap"))
-                               {
-                                       shader->backgroundlayer = NULL;
-                                       shader->primarylayer = shader->layers + 1;
-                               }
-                       }
-               }
-               Mem_Free(f);
-       }
-}
-
-q3shaderinfo_t *Mod_Q3BSP_LookupShader(const char *name)
-{
-       int i;
-       for (i = 0;i < Q3SHADER_MAXSHADERS;i++)
-               if (!strcasecmp(q3shaders_shaders[i].name, name))
-                       return q3shaders_shaders + i;
-       return NULL;
-}
-
 static void Mod_Q3BSP_LoadTextures(lump_t *l)
 {
        q3dtexture_t *in;
@@ -4484,143 +4135,10 @@ static void Mod_Q3BSP_LoadTextures(lump_t *l)
        if (cls.state == ca_dedicated)
                return;
 
-       // parse the Q3 shader files
-       Mod_Q3BSP_LoadShaders();
-
        c = 0;
        for (i = 0;i < count;i++, in++, out++)
-       {
-               q3shaderinfo_t *shader;
-               shader = Mod_Q3BSP_LookupShader(out->name);
-               if (shader)
-               {
-                       out->surfaceparms = shader->surfaceparms;
-                       out->textureflags = shader->textureflags;
-                       out->basematerialflags = 0;
-                       if (shader->surfaceparms & Q3SURFACEPARM_SKY)
-                       {
-                               out->basematerialflags |= MATERIALFLAG_SKY | MATERIALFLAG_NOSHADOW;
-                               if (shader->skyboxname[0])
-                               {
-                                       // quake3 seems to append a _ to the skybox name, so this must do so as well
-                                       dpsnprintf(loadmodel->brush.skybox, sizeof(loadmodel->brush.skybox), "%s_", shader->skyboxname);
-                               }
-                       }
-                       else if ((out->surfaceflags & Q3SURFACEFLAG_NODRAW) || shader->numlayers == 0)
-                               out->basematerialflags |= MATERIALFLAG_NODRAW | MATERIALFLAG_NOSHADOW;
-                       else if (shader->surfaceparms & Q3SURFACEPARM_LAVA)
-                               out->basematerialflags |= MATERIALFLAG_WATER | MATERIALFLAG_LIGHTBOTHSIDES | MATERIALFLAG_FULLBRIGHT | MATERIALFLAG_NOSHADOW;
-                       else if (shader->surfaceparms & Q3SURFACEPARM_SLIME)
-                               out->basematerialflags |= MATERIALFLAG_WATER | MATERIALFLAG_LIGHTBOTHSIDES | MATERIALFLAG_WATERALPHA | MATERIALFLAG_NOSHADOW;
-                       else if (shader->surfaceparms & Q3SURFACEPARM_WATER)
-                               out->basematerialflags |= MATERIALFLAG_WATER | MATERIALFLAG_LIGHTBOTHSIDES | MATERIALFLAG_WATERALPHA | MATERIALFLAG_NOSHADOW;
-                       else
-                               out->basematerialflags |= MATERIALFLAG_WALL;
-                       if (shader->layers[0].alphatest)
-                               out->basematerialflags |= MATERIALFLAG_ALPHATEST | MATERIALFLAG_NOSHADOW;
-                       if (shader->textureflags & Q3TEXTUREFLAG_TWOSIDED)
-                               out->basematerialflags |= MATERIALFLAG_NOSHADOW | MATERIALFLAG_NOCULLFACE;
-                       if (shader->textureflags & (Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2))
-                               out->basematerialflags |= MATERIALFLAG_NOSHADOW;
-                       out->customblendfunc[0] = GL_ONE;
-                       out->customblendfunc[1] = GL_ZERO;
-                       if (shader->numlayers > 0)
-                       {
-                               out->customblendfunc[0] = shader->layers[0].blendfunc[0];
-                               out->customblendfunc[1] = shader->layers[0].blendfunc[1];
-/*
-Q3 shader blendfuncs actually used in the game (* = supported by DP)
-* additive               GL_ONE GL_ONE
-  additive weird         GL_ONE GL_SRC_ALPHA
-  additive weird 2       GL_ONE GL_ONE_MINUS_SRC_ALPHA
-* alpha                  GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA
-  alpha inverse          GL_ONE_MINUS_SRC_ALPHA GL_SRC_ALPHA
-  brighten               GL_DST_COLOR GL_ONE
-  brighten               GL_ONE GL_SRC_COLOR
-  brighten weird         GL_DST_COLOR GL_ONE_MINUS_DST_ALPHA
-  brighten weird 2       GL_DST_COLOR GL_SRC_ALPHA
-* modulate               GL_DST_COLOR GL_ZERO
-* modulate               GL_ZERO GL_SRC_COLOR
-  modulate inverse       GL_ZERO GL_ONE_MINUS_SRC_COLOR
-  modulate inverse alpha GL_ZERO GL_SRC_ALPHA
-  modulate weird inverse GL_ONE_MINUS_DST_COLOR GL_ZERO
-* modulate x2            GL_DST_COLOR GL_SRC_COLOR
-* no blend               GL_ONE GL_ZERO
-  nothing                GL_ZERO GL_ONE
-*/
-                               // if not opaque, figure out what blendfunc to use
-                               if (shader->layers[0].blendfunc[0] != GL_ONE || shader->layers[0].blendfunc[1] != GL_ZERO)
-                               {
-                                       if (shader->layers[0].blendfunc[0] == GL_ONE && shader->layers[0].blendfunc[1] == GL_ONE)
-                                               out->basematerialflags |= MATERIALFLAG_ADD | MATERIALFLAG_BLENDED | MATERIALFLAG_NOSHADOW;
-                                       else if (shader->layers[0].blendfunc[0] == GL_SRC_ALPHA && shader->layers[0].blendfunc[1] == GL_ONE)
-                                               out->basematerialflags |= MATERIALFLAG_ADD | MATERIALFLAG_BLENDED | MATERIALFLAG_NOSHADOW;
-                                       else if (shader->layers[0].blendfunc[0] == GL_SRC_ALPHA && shader->layers[0].blendfunc[1] == GL_ONE_MINUS_SRC_ALPHA)
-                                               out->basematerialflags |= MATERIALFLAG_ALPHA | MATERIALFLAG_BLENDED | MATERIALFLAG_NOSHADOW;
-                                       else
-                                               out->basematerialflags |= MATERIALFLAG_CUSTOMBLEND | MATERIALFLAG_FULLBRIGHT | MATERIALFLAG_BLENDED | MATERIALFLAG_NOSHADOW;
-                               }
-                       }
-                       if (!shader->lighting)
-                               out->basematerialflags |= MATERIALFLAG_FULLBRIGHT;
-                       if (shader->primarylayer)
-                       {
-                               int j;
-                               out->numskinframes = shader->primarylayer->numframes;
-                               out->skinframerate = shader->primarylayer->framerate;
-                               for (j = 0;j < shader->primarylayer->numframes;j++)
-                                       if (!(out->skinframes[j] = R_SkinFrame_LoadExternal(shader->primarylayer->texturename[j], ((shader->surfaceparms & Q3SURFACEPARM_NOMIPMAPS) ? 0 : TEXF_MIPMAP) | TEXF_ALPHA | TEXF_PRECACHE | ((!r_picmipworld.integer || (shader->textureflags & Q3TEXTUREFLAG_NOPICMIP)) ? 0 : TEXF_PICMIP) | (shader->primarylayer->clampmap ? TEXF_CLAMP : 0), false)))
-                                               Con_DPrintf("%s: could not load texture \"%s\" (frame %i) for shader \"%s\"\n", loadmodel->name, shader->primarylayer->texturename[j], j, out->name);
-                       }
-                       if (shader->backgroundlayer)
-                       {
-                               int j;
-                               out->backgroundnumskinframes = shader->backgroundlayer->numframes;
-                               out->backgroundskinframerate = shader->backgroundlayer->framerate;
-                               for (j = 0;j < shader->backgroundlayer->numframes;j++)
-                               {
-                                       if (!(out->backgroundskinframes[j] = R_SkinFrame_LoadExternal(shader->backgroundlayer->texturename[j], ((shader->surfaceparms & Q3SURFACEPARM_NOMIPMAPS) ? 0 : TEXF_MIPMAP) | TEXF_ALPHA | TEXF_PRECACHE | ((!r_picmipworld.integer || (shader->textureflags & Q3TEXTUREFLAG_NOPICMIP)) ? 0 : TEXF_PICMIP) | (shader->backgroundlayer->clampmap ? TEXF_CLAMP : 0), false)))
-                                       {
-                                               Con_DPrintf("%s: could not load texture \"%s\" (frame %i) for shader \"%s\"\n", loadmodel->name, shader->backgroundlayer->texturename[j], j, out->name);
-                                               out->backgroundskinframes[j] = R_SkinFrame_LoadMissing();
-                                       }
-                               }
-                       }
-               }
-               else if (!strcmp(out->name, "noshader"))
-                       out->surfaceparms = 0;
-               else
-               {
+               if (Mod_LoadTextureFromQ3Shader(out, out->name, false, true, false))
                        c++;
-                       Con_DPrintf("%s: No shader found for texture \"%s\"\n", loadmodel->name, out->name);
-                       out->surfaceparms = 0;
-                       if (out->surfaceflags & Q3SURFACEFLAG_NODRAW)
-                               out->basematerialflags |= MATERIALFLAG_NODRAW | MATERIALFLAG_NOSHADOW;
-                       else if (out->surfaceflags & Q3SURFACEFLAG_SKY)
-                               out->basematerialflags |= MATERIALFLAG_SKY | MATERIALFLAG_NOSHADOW;
-                       else
-                               out->basematerialflags |= MATERIALFLAG_WALL;
-                       // these are defaults
-                       //if (!strncmp(out->name, "textures/skies/", 15))
-                       //      out->surfaceparms |= Q3SURFACEPARM_SKY;
-                       //if (!strcmp(out->name, "caulk") || !strcmp(out->name, "common/caulk") || !strcmp(out->name, "textures/common/caulk")
-                       // || !strcmp(out->name, "nodraw") || !strcmp(out->name, "common/nodraw") || !strcmp(out->name, "textures/common/nodraw"))
-                       //      out->surfaceparms |= Q3SURFACEPARM_NODRAW;
-                       //if (R_TextureHasAlpha(out->skinframes[0].base))
-                       //      out->surfaceparms |= Q3SURFACEPARM_TRANS;
-                       out->numskinframes = 1;
-                       if (!(out->skinframes[0] = R_SkinFrame_LoadExternal(out->name, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE | (r_picmipworld.integer ? TEXF_PICMIP : 0), false)))
-                               Con_DPrintf("%s: could not load texture for missing shader \"%s\"\n", loadmodel->name, out->name);
-               }
-               // init the animation variables
-               out->currentframe = out;
-               if (out->numskinframes < 1)
-                       out->numskinframes = 1;
-               if (!out->skinframes[0])
-                       out->skinframes[0] = R_SkinFrame_LoadMissing();
-               out->currentskinframe = out->skinframes[0];
-               out->backgroundcurrentskinframe = out->backgroundskinframes[0];
-       }
        if (c)
                Con_DPrintf("%s: %i textures missing shaders\n", loadmodel->name, c);
 }