rmeshstate_t m;
R_Mesh_Matrix(&ent->matrix);
memset(&m, 0, sizeof(m));
- if (ent->effects & EF_ADDITIVE)
+ if ((ent->effects & EF_ADDITIVE) || (face->texture->textureflags & Q3TEXTUREFLAG_ADDITIVE))
GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
else
GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
m.pointer_color = varray_color4f;
}
- m.pointer_vertex = face->data_vertex3f;
+ if (face->texture->textureflags & (Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2))
+ {
+ int i, j;
+ float f, center[3], center2[3], forward[3], right[3], up[3], v[4][3];
+ matrix4x4_t matrix1, imatrix1;
+ R_Mesh_Matrix(&r_identitymatrix);
+ // a single autosprite surface can contain multiple sprites...
+ for (j = 0;j < face->num_vertices - 3;j += 4)
+ {
+ VectorClear(center);
+ for (i = 0;i < 4;i++)
+ VectorAdd(center, face->data_vertex3f + (j+i) * 3, center);
+ VectorScale(center, 0.25f, center);
+ Matrix4x4_Transform(&ent->matrix, center, center2);
+ // FIXME: calculate vectors from triangle edges instead of using texture vectors as an easy way out?
+ Matrix4x4_FromVectors(&matrix1, face->data_normal3f + j*3, face->data_svector3f + j*3, face->data_tvector3f + j*3, center);
+ Matrix4x4_Invert_Simple(&imatrix1, &matrix1);
+ for (i = 0;i < 4;i++)
+ Matrix4x4_Transform(&imatrix1, face->data_vertex3f + (j+i)*3, v[i]);
+ if (face->texture->textureflags & Q3TEXTUREFLAG_AUTOSPRITE2)
+ {
+ CL_SparkShower (center, vec3_origin, 1);
+ forward[0] = r_vieworigin[0] - center2[0];
+ forward[1] = r_vieworigin[1] - center2[1];
+ forward[2] = 0;
+ VectorNormalize(forward);
+ right[0] = forward[1];
+ right[1] = -forward[0];
+ right[2] = 0;
+ up[0] = 0;
+ up[1] = 0;
+ up[2] = 1;
+ }
+ else
+ {
+ VectorCopy(r_viewforward, forward);
+ VectorCopy(r_viewright, right);
+ VectorCopy(r_viewup, up);
+ }
+ for (i = 0;i < 4;i++)
+ VectorMAMAMAM(1, center2, v[i][0], forward, v[i][1], right, v[i][2], up, varray_vertex3f + (i+j) * 3);
+ }
+ m.pointer_vertex = varray_vertex3f;
+ }
+ else
+ m.pointer_vertex = face->data_vertex3f;
R_Mesh_State(&m);
- qglDisable(GL_CULL_FACE);
+ if (face->texture->textureflags & Q3TEXTUREFLAG_TWOSIDED)
+ qglDisable(GL_CULL_FACE);
GL_LockArrays(0, face->num_vertices);
R_Mesh_Draw(face->num_vertices, face->num_triangles, face->data_element3i);
GL_LockArrays(0, 0);
- qglEnable(GL_CULL_FACE);
+ if (face->texture->textureflags & Q3TEXTUREFLAG_TWOSIDED)
+ qglEnable(GL_CULL_FACE);
}
void R_Q3BSP_DrawFaceList(entity_render_t *ent, q3mtexture_t *t, int texturenumfaces, q3msurface_t **texturefacelist)
GL_DepthMask(true);
GL_DepthTest(true);
GL_BlendFunc(GL_ONE, GL_ZERO);
+ qglDisable(GL_CULL_FACE);
memset(&m, 0, sizeof(m));
for (texturefaceindex = 0;texturefaceindex < texturenumfaces;texturefaceindex++)
{
R_Mesh_Draw(face->num_vertices, face->num_triangles, face->data_element3i);
GL_LockArrays(0, 0);
}
+ qglEnable(GL_CULL_FACE);
return;
}
// anything else is a typical wall, lightmap * texture + glow
GL_DepthTest(true);
GL_BlendFunc(GL_ONE, GL_ZERO);
GL_Color(1, 1, 1, 1);
+ if (t->textureflags & Q3TEXTUREFLAG_TWOSIDED)
+ qglDisable(GL_CULL_FACE);
memset(&m, 0, sizeof(m));
m.tex[0] = R_GetTexture(t->skin.base);
for (texturefaceindex = 0;texturefaceindex < texturenumfaces;texturefaceindex++)
GL_LockArrays(0, 0);
}
}
+ if (t->textureflags & Q3TEXTUREFLAG_TWOSIDED)
+ qglEnable(GL_CULL_FACE);
return;
}
+ if (t->textureflags & Q3TEXTUREFLAG_TWOSIDED)
+ qglDisable(GL_CULL_FACE);
if (r_lightmapintensity <= 0)
{
GL_DepthMask(true);
GL_LockArrays(0, 0);
}
}
+ if (t->textureflags & Q3TEXTUREFLAG_TWOSIDED)
+ qglEnable(GL_CULL_FACE);
}
void R_Q3BSP_DrawFaces(entity_render_t *ent, int skyfaces)
{
if (BoxesOverlap(lightmins, lightmaxs, surface->mins, surface->maxs) && !(surface->texture->surfaceparms & Q3SURFACEPARM_TRANS) && !(surface->texture->surfaceflags & (Q3SURFACEFLAG_SKY | Q3SURFACEFLAG_NODRAW)) && surface->num_triangles)
{
- for (triangleindex = 0, t = surface->num_firstshadowmeshtriangle, e = model->brush.shadowmesh->element3i + t * 3;triangleindex < surface->num_triangles;triangleindex++, t++, e += 3)
+ if (surface->texture->textureflags & Q3TEXTUREFLAG_TWOSIDED)
{
- v[0] = model->brush.shadowmesh->vertex3f + e[0] * 3;
- v[1] = model->brush.shadowmesh->vertex3f + e[1] * 3;
- v[2] = model->brush.shadowmesh->vertex3f + e[2] * 3;
- if (PointInfrontOfTriangle(relativelightorigin, v[0], v[1], v[2]) && lightmaxs[0] > min(v[0][0], min(v[1][0], v[2][0])) && lightmins[0] < max(v[0][0], max(v[1][0], v[2][0])) && lightmaxs[1] > min(v[0][1], min(v[1][1], v[2][1])) && lightmins[1] < max(v[0][1], max(v[1][1], v[2][1])) && lightmaxs[2] > min(v[0][2], min(v[1][2], v[2][2])) && lightmins[2] < max(v[0][2], max(v[1][2], v[2][2])))
+ for (triangleindex = 0, t = surface->num_firstshadowmeshtriangle, e = model->brush.shadowmesh->element3i + t * 3;triangleindex < surface->num_triangles;triangleindex++, t++, e += 3)
{
- SETPVSBIT(outsurfacepvs, surfaceindex);
- outsurfacelist[outnumsurfaces++] = surfaceindex;
- break;
+ v[0] = model->brush.shadowmesh->vertex3f + e[0] * 3;
+ v[1] = model->brush.shadowmesh->vertex3f + e[1] * 3;
+ v[2] = model->brush.shadowmesh->vertex3f + e[2] * 3;
+ if (lightmaxs[0] > min(v[0][0], min(v[1][0], v[2][0])) && lightmins[0] < max(v[0][0], max(v[1][0], v[2][0])) && lightmaxs[1] > min(v[0][1], min(v[1][1], v[2][1])) && lightmins[1] < max(v[0][1], max(v[1][1], v[2][1])) && lightmaxs[2] > min(v[0][2], min(v[1][2], v[2][2])) && lightmins[2] < max(v[0][2], max(v[1][2], v[2][2])))
+ {
+ SETPVSBIT(outsurfacepvs, surfaceindex);
+ outsurfacelist[outnumsurfaces++] = surfaceindex;
+ break;
+ }
+ }
+ }
+ else
+ {
+ for (triangleindex = 0, t = surface->num_firstshadowmeshtriangle, e = model->brush.shadowmesh->element3i + t * 3;triangleindex < surface->num_triangles;triangleindex++, t++, e += 3)
+ {
+ v[0] = model->brush.shadowmesh->vertex3f + e[0] * 3;
+ v[1] = model->brush.shadowmesh->vertex3f + e[1] * 3;
+ v[2] = model->brush.shadowmesh->vertex3f + e[2] * 3;
+ if (PointInfrontOfTriangle(relativelightorigin, v[0], v[1], v[2]) && lightmaxs[0] > min(v[0][0], min(v[1][0], v[2][0])) && lightmins[0] < max(v[0][0], max(v[1][0], v[2][0])) && lightmaxs[1] > min(v[0][1], min(v[1][1], v[2][1])) && lightmins[1] < max(v[0][1], max(v[1][1], v[2][1])) && lightmaxs[2] > min(v[0][2], min(v[1][2], v[2][2])) && lightmins[2] < max(v[0][2], max(v[1][2], v[2][2])))
+ {
+ SETPVSBIT(outsurfacepvs, surfaceindex);
+ outsurfacelist[outnumsurfaces++] = surfaceindex;
+ break;
+ }
}
}
}
{
surface = model->brushq3.data_faces + surfacelist[surfacelistindex];
// FIXME: check some manner of face->rendermode here?
- if (!(surface->texture->surfaceflags & Q3SURFACEFLAG_NODRAW) && !(surface->texture->surfaceparms & Q3SURFACEPARM_TRANS))
+ if (!(surface->texture->surfaceflags & Q3SURFACEFLAG_NODRAW) && !(surface->texture->surfaceparms & (Q3SURFACEPARM_SKY | Q3SURFACEPARM_TRANS)) && !(surface->texture->textureflags & Q3TEXTUREFLAG_TWOSIDED))
R_Shadow_MarkVolumeFromBox(surface->num_firstshadowmeshtriangle, surface->num_triangles, model->brush.shadowmesh->vertex3f, model->brush.shadowmesh->element3i, relativelightorigin, lightmins, lightmaxs, surface->mins, surface->maxs);
}
R_Shadow_VolumeFromList(model->brush.shadowmesh->numverts, model->brush.shadowmesh->numtriangles, model->brush.shadowmesh->vertex3f, model->brush.shadowmesh->element3i, model->brush.shadowmesh->neighbor3i, relativelightorigin, lightradius + model->radius + r_shadow_projectdistance.value, numshadowmark, shadowmarklist);
Mod_ShadowMesh_AddMesh(r_shadow_mempool, r_shadow_compilingrtlight->static_meshchain_light, surface->texture->skin.base, surface->texture->skin.gloss, surface->texture->skin.nmap, surface->data_vertex3f, surface->data_svector3f, surface->data_tvector3f, surface->data_normal3f, surface->data_texcoordtexture2f, surface->num_triangles, surface->data_element3i);
}
else if (!(surface->texture->surfaceflags & Q3SURFACEFLAG_NODRAW) && surface->num_triangles)
+ {
+ if (surface->texture->textureflags & Q3TEXTUREFLAG_TWOSIDED)
+ qglDisable(GL_CULL_FACE);
R_Shadow_RenderLighting(surface->num_vertices, surface->num_triangles, surface->data_element3i, surface->data_vertex3f, surface->data_svector3f, surface->data_tvector3f, surface->data_normal3f, surface->data_texcoordtexture2f, relativelightorigin, relativeeyeorigin, lightcolor, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, surface->texture->skin.base, surface->texture->skin.nmap, surface->texture->skin.gloss, lightcubemap, LIGHTING_DIFFUSE | LIGHTING_SPECULAR);
+ if (surface->texture->textureflags & Q3TEXTUREFLAG_TWOSIDED)
+ qglEnable(GL_CULL_FACE);
+ }
}
}
}
fssearch_t *search;
char *f;
const char *text;
- int flags;
+ int flags, flags2, numparameters, passnumber;
char shadername[Q3PATHLENGTH];
char sky[Q3PATHLENGTH];
+ char firstpasstexturename[Q3PATHLENGTH];
+ char parameter[4][Q3PATHLENGTH];
in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
out->surfaceflags = LittleLong(in->surfaceflags);
out->nativecontents = LittleLong(in->contents);
out->supercontents = Mod_Q3BSP_SuperContentsFromNativeContents(loadmodel, out->nativecontents);
- Mod_LoadSkinFrame(&out->skin, out->name, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE | TEXF_PICMIP, false, true, true);
out->surfaceparms = -1;
}
{
strlcpy (shadername, com_token, sizeof (shadername));
flags = 0;
+ flags2 = 0;
sky[0] = 0;
+ passnumber = 0;
+ firstpasstexturename[0] = 0;
if (COM_ParseToken(&text, false) && !strcasecmp(com_token, "{"))
{
while (COM_ParseToken(&text, false))
{
if (!strcasecmp(com_token, "}"))
break;
+ if (!strcasecmp(com_token, "\n"))
+ continue;
+ numparameters = 0;
+ for (j = 0;strcasecmp(com_token, "\n") && strcasecmp(com_token, "}");j++)
+ {
+ if (j < 4)
+ {
+ strlcpy(parameter[j], com_token, sizeof(parameter[j]));
+ numparameters = j + 1;
+ }
+ if (!COM_ParseToken(&text, true))
+ break;
+ }
+ Con_Printf("%s %i: ", shadername, passnumber);
+ for (j = 0;j < numparameters;j++)
+ Con_Printf(" %s", parameter[j]);
+ Con_Print("\n");
+ if (passnumber == 0 && numparameters >= 1)
+ {
+ if (!strcasecmp(parameter[0], "blendfunc"))
+ {
+ Con_Printf("!\n");
+ if (numparameters == 2 && !strcasecmp(parameter[1], "add"))
+ flags2 |= Q3TEXTUREFLAG_ADDITIVE;
+ else if (numparameters == 3 && !strcasecmp(parameter[1], "gl_one") && !strcasecmp(parameter[2], "gl_one"))
+ flags2 |= Q3TEXTUREFLAG_ADDITIVE;
+ else if (numparameters == 3 && !strcasecmp(parameter[1], "gl_src_alpha") && !strcasecmp(parameter[2], "gl_one"))
+ flags2 |= Q3TEXTUREFLAG_ADDITIVE;
+ }
+ else if (numparameters >= 2 && (!strcasecmp(parameter[0], "map") || !strcasecmp(parameter[0], "clampmap")))
+ strlcpy(firstpasstexturename, parameter[1], sizeof(firstpasstexturename));
+ else if (numparameters >= 3 && !strcasecmp(parameter[0], "animmap"))
+ strlcpy(firstpasstexturename, parameter[2], sizeof(firstpasstexturename));
+ }
+ // break out a level if it was }
+ if (!strcasecmp(com_token, "}"))
+ break;
}
+ passnumber++;
+ continue;
}
- else if (!strcasecmp(com_token, "surfaceparm"))
+ numparameters = 0;
+ for (j = 0;strcasecmp(com_token, "\n") && strcasecmp(com_token, "}");j++)
{
- if (COM_ParseToken(&text, true) && strcasecmp(com_token, "\n"))
+ if (j < 4)
{
- if (!strcasecmp(com_token, "alphashadow"))
- flags |= Q3SURFACEPARM_ALPHASHADOW;
- else if (!strcasecmp(com_token, "areaportal"))
- flags |= Q3SURFACEPARM_AREAPORTAL;
- else if (!strcasecmp(com_token, "clusterportal"))
- flags |= Q3SURFACEPARM_CLUSTERPORTAL;
- else if (!strcasecmp(com_token, "detail"))
- flags |= Q3SURFACEPARM_DETAIL;
- else if (!strcasecmp(com_token, "donotenter"))
- flags |= Q3SURFACEPARM_DONOTENTER;
- else if (!strcasecmp(com_token, "fog"))
- flags |= Q3SURFACEPARM_FOG;
- else if (!strcasecmp(com_token, "lava"))
- flags |= Q3SURFACEPARM_LAVA;
- else if (!strcasecmp(com_token, "lightfilter"))
- flags |= Q3SURFACEPARM_LIGHTFILTER;
- else if (!strcasecmp(com_token, "metalsteps"))
- flags |= Q3SURFACEPARM_METALSTEPS;
- else if (!strcasecmp(com_token, "nodamage"))
- flags |= Q3SURFACEPARM_NODAMAGE;
- else if (!strcasecmp(com_token, "nodlight"))
- flags |= Q3SURFACEPARM_NODLIGHT;
- else if (!strcasecmp(com_token, "nodraw"))
- flags |= Q3SURFACEPARM_NODRAW;
- else if (!strcasecmp(com_token, "nodrop"))
- flags |= Q3SURFACEPARM_NODROP;
- else if (!strcasecmp(com_token, "noimpact"))
- flags |= Q3SURFACEPARM_NOIMPACT;
- else if (!strcasecmp(com_token, "nolightmap"))
- flags |= Q3SURFACEPARM_NOLIGHTMAP;
- else if (!strcasecmp(com_token, "nomarks"))
- flags |= Q3SURFACEPARM_NOMARKS;
- else if (!strcasecmp(com_token, "nomipmaps"))
- flags |= Q3SURFACEPARM_NOMIPMAPS;
- else if (!strcasecmp(com_token, "nonsolid"))
- flags |= Q3SURFACEPARM_NONSOLID;
- else if (!strcasecmp(com_token, "origin"))
- flags |= Q3SURFACEPARM_ORIGIN;
- else if (!strcasecmp(com_token, "playerclip"))
- flags |= Q3SURFACEPARM_PLAYERCLIP;
- else if (!strcasecmp(com_token, "sky"))
- flags |= Q3SURFACEPARM_SKY;
- else if (!strcasecmp(com_token, "slick"))
- flags |= Q3SURFACEPARM_SLICK;
- else if (!strcasecmp(com_token, "slime"))
- flags |= Q3SURFACEPARM_SLIME;
- else if (!strcasecmp(com_token, "structural"))
- flags |= Q3SURFACEPARM_STRUCTURAL;
- else if (!strcasecmp(com_token, "trans"))
- flags |= Q3SURFACEPARM_TRANS;
- else if (!strcasecmp(com_token, "water"))
- flags |= Q3SURFACEPARM_WATER;
- else
- Con_Printf("%s parsing warning: unknown surfaceparm \"%s\"\n", search->filenames[i], com_token);
- if (!COM_ParseToken(&text, true) || strcasecmp(com_token, "\n"))
- {
- Con_Printf("%s parsing error: surfaceparm only takes one parameter.\n", search->filenames[i]);
- goto parseerror;
- }
+ strlcpy(parameter[j], com_token, sizeof(parameter[j]));
+ numparameters = j + 1;
}
+ if (!COM_ParseToken(&text, true))
+ break;
+ }
+ if (i == 0 && !strcasecmp(com_token, "}"))
+ break;
+ Con_Printf("%s: ", shadername);
+ 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"))
+ flags |= Q3SURFACEPARM_ALPHASHADOW;
+ else if (!strcasecmp(parameter[1], "areaportal"))
+ flags |= Q3SURFACEPARM_AREAPORTAL;
+ else if (!strcasecmp(parameter[1], "clusterportal"))
+ flags |= Q3SURFACEPARM_CLUSTERPORTAL;
+ else if (!strcasecmp(parameter[1], "detail"))
+ flags |= Q3SURFACEPARM_DETAIL;
+ else if (!strcasecmp(parameter[1], "donotenter"))
+ flags |= Q3SURFACEPARM_DONOTENTER;
+ else if (!strcasecmp(parameter[1], "fog"))
+ flags |= Q3SURFACEPARM_FOG;
+ else if (!strcasecmp(parameter[1], "lava"))
+ flags |= Q3SURFACEPARM_LAVA;
+ else if (!strcasecmp(parameter[1], "lightfilter"))
+ flags |= Q3SURFACEPARM_LIGHTFILTER;
+ else if (!strcasecmp(parameter[1], "metalsteps"))
+ flags |= Q3SURFACEPARM_METALSTEPS;
+ else if (!strcasecmp(parameter[1], "nodamage"))
+ flags |= Q3SURFACEPARM_NODAMAGE;
+ else if (!strcasecmp(parameter[1], "nodlight"))
+ flags |= Q3SURFACEPARM_NODLIGHT;
+ else if (!strcasecmp(parameter[1], "nodraw"))
+ flags |= Q3SURFACEPARM_NODRAW;
+ else if (!strcasecmp(parameter[1], "nodrop"))
+ flags |= Q3SURFACEPARM_NODROP;
+ else if (!strcasecmp(parameter[1], "noimpact"))
+ flags |= Q3SURFACEPARM_NOIMPACT;
+ else if (!strcasecmp(parameter[1], "nolightmap"))
+ flags |= Q3SURFACEPARM_NOLIGHTMAP;
+ else if (!strcasecmp(parameter[1], "nomarks"))
+ flags |= Q3SURFACEPARM_NOMARKS;
+ else if (!strcasecmp(parameter[1], "nomipmaps"))
+ flags |= Q3SURFACEPARM_NOMIPMAPS;
+ else if (!strcasecmp(parameter[1], "nonsolid"))
+ flags |= Q3SURFACEPARM_NONSOLID;
+ else if (!strcasecmp(parameter[1], "origin"))
+ flags |= Q3SURFACEPARM_ORIGIN;
+ else if (!strcasecmp(parameter[1], "playerclip"))
+ flags |= Q3SURFACEPARM_PLAYERCLIP;
+ else if (!strcasecmp(parameter[1], "sky"))
+ flags |= Q3SURFACEPARM_SKY;
+ else if (!strcasecmp(parameter[1], "slick"))
+ flags |= Q3SURFACEPARM_SLICK;
+ else if (!strcasecmp(parameter[1], "slime"))
+ flags |= Q3SURFACEPARM_SLIME;
+ else if (!strcasecmp(parameter[1], "structural"))
+ flags |= Q3SURFACEPARM_STRUCTURAL;
+ else if (!strcasecmp(parameter[1], "trans"))
+ flags |= Q3SURFACEPARM_TRANS;
+ else if (!strcasecmp(parameter[1], "water"))
+ flags |= Q3SURFACEPARM_WATER;
else
- {
- Con_Printf("%s parsing error: surfaceparm expects a parameter.\n", search->filenames[i]);
- goto parseerror;
- }
+ Con_Printf("%s parsing warning: unknown surfaceparm \"%s\"\n", search->filenames[i], parameter[1]);
}
- else if (!strcasecmp(com_token, "sky"))
+ else if (!strcasecmp(parameter[0], "sky") && numparameters >= 2)
+ strlcpy(sky, parameter[1], sizeof(sky));
+ else if (!strcasecmp(parameter[0], "skyparms") && numparameters >= 2)
{
- if (COM_ParseToken(&text, true) && strcasecmp(com_token, "\n"))
- if (strlen(com_token) < sizeof(sky))
- strcpy(sky, com_token);
+ if (!atoi(parameter[1]) && strcasecmp(parameter[1], "-"))
+ strlcpy(sky, parameter[1], sizeof(sky));
}
- else if (!strcasecmp(com_token, "skyparms"))
+ else if (!strcasecmp(parameter[0], "cull") && numparameters >= 2)
{
- if (COM_ParseToken(&text, true) && strcasecmp(com_token, "\n"))
- {
- if (strlen(com_token) < sizeof(sky) && !atoi(com_token) && strcasecmp(com_token, "-"))
- strcpy(sky, com_token);
- if (COM_ParseToken(&text, true) && strcasecmp(com_token, "\n"))
- COM_ParseToken(&text, true);
- }
+ if (!strcasecmp(parameter[1], "disable") || !strcasecmp(parameter[1], "none") || !strcasecmp(parameter[1], "twosided"))
+ flags2 |= Q3TEXTUREFLAG_TWOSIDED;
}
- else
+ else if (!strcasecmp(parameter[0], "nomipmaps"))
+ flags2 |= Q3TEXTUREFLAG_NOMIPMAPS;
+ else if (!strcasecmp(parameter[0], "nopicmip"))
+ flags2 |= Q3TEXTUREFLAG_NOPICMIP;
+ else if (!strcasecmp(parameter[0], "deformvertexes") && numparameters >= 2)
{
- // look for linebreak or }
- while(COM_ParseToken(&text, true) && strcasecmp(com_token, "\n") && strcasecmp(com_token, "}"));
- // break out to top level if it was }
- if (!strcasecmp(com_token, "}"))
- break;
+ if (!strcasecmp(parameter[1], "autosprite") && numparameters == 2)
+ flags2 |= Q3TEXTUREFLAG_AUTOSPRITE;
+ if (!strcasecmp(parameter[1], "autosprite2") && numparameters == 2)
+ flags2 |= Q3TEXTUREFLAG_AUTOSPRITE2;
}
}
+ // force transparent render path for a number of odd
+ // shader effects to avoid bogging down the normal
+ // render path unnecessarily
+ if (flags2 & (Q3TEXTUREFLAG_ADDITIVE | Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2))
+ flags |= Q3SURFACEPARM_TRANS;
// add shader to list (shadername and flags)
// actually here we just poke into the texture settings
for (j = 0, out = loadmodel->brushq3.data_textures;j < loadmodel->brushq3.num_textures;j++, out++)
if (!strcasecmp(out->name, shadername))
{
out->surfaceparms = flags;
+ out->textureflags = flags2;
+ strlcpy(out->firstpasstexturename, firstpasstexturename, sizeof(out->firstpasstexturename));
if ((flags & Q3SURFACEPARM_SKY) && sky[0])
{
// quake3 seems to append a _ to the skybox name, so this must do so as well
Con_DPrintf("%s: No shader found for texture \"%s\"\n", loadmodel->name, out->name);
out->surfaceparms = 0;
// these are defaults
- 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 (!strncmp(out->name, "textures/skies/", 15))
out->surfaceparms |= Q3SURFACEPARM_SKY;
- if (R_TextureHasAlpha(out->skin.base))
- out->surfaceparms |= Q3SURFACEPARM_TRANS;
+ //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->skin.base))
+ // out->surfaceparms |= Q3SURFACEPARM_TRANS;
}
+ if (!Mod_LoadSkinFrame(&out->skin, out->name, (((out->textureflags & Q3TEXTUREFLAG_NOMIPMAPS) || (out->surfaceparms & Q3SURFACEPARM_NOMIPMAPS)) ? 0 : TEXF_MIPMAP) | TEXF_ALPHA | TEXF_PRECACHE | (out->textureflags & Q3TEXTUREFLAG_NOPICMIP ? 0 : TEXF_PICMIP), false, true, true))
+ Mod_LoadSkinFrame(&out->skin, out->firstpasstexturename, (((out->textureflags & Q3TEXTUREFLAG_NOMIPMAPS) || (out->surfaceparms & Q3SURFACEPARM_NOMIPMAPS)) ? 0 : TEXF_MIPMAP) | TEXF_ALPHA | TEXF_PRECACHE | (out->textureflags & Q3TEXTUREFLAG_NOPICMIP ? 0 : TEXF_PICMIP), false, true, true);
}
Con_DPrintf("%s: %i textures missing shaders\n", loadmodel->name, c);
}