cvar_t csqc_progcrc = {CVAR_CLIENT | CVAR_READONLY, "csqc_progcrc","-1","CRC of csprogs.dat file to load (-1 is none), only used during level changes and then reset to -1"};
cvar_t csqc_progsize = {CVAR_CLIENT | CVAR_READONLY, "csqc_progsize","-1","file size of csprogs.dat file to load (-1 is none), only used during level changes and then reset to -1"};
cvar_t csqc_usedemoprogs = {CVAR_CLIENT, "csqc_usedemoprogs","1","use csprogs stored in demos"};
+cvar_t csqc_polygons_defaultmaterial_nocullface = {CVAR_CLIENT, "csqc_polygons_defaultmaterial_nocullface", "0", "use 'cull none' behavior in the default shader for rendering R_PolygonBegin - warning: enabling this is not consistent with FTEQW behavior on this feature"};
cvar_t cl_shownet = {CVAR_CLIENT, "cl_shownet","0","1 = print packet size, 2 = print packet message list"};
cvar_t cl_nolerp = {CVAR_CLIENT, "cl_nolerp", "0","network update smoothing"};
void CL_MeshEntities_Scene_FinalizeRenderEntity(void)
{
entity_t *ent = &cl_meshentities[MESH_SCENE];
- if (ent->render.model->num_surfaces)
- {
- Mod_Mesh_Finalize(ent->render.model);
- VectorCopy(ent->render.model->normalmins, ent->render.mins);
- VectorCopy(ent->render.model->normalmaxs, ent->render.maxs);
- }
+ Mod_Mesh_Finalize(ent->render.model);
+ VectorCopy(ent->render.model->normalmins, ent->render.mins);
+ VectorCopy(ent->render.model->normalmaxs, ent->render.maxs);
}
static void CL_MeshEntities_Shutdown(void)
Cmd_AddCommand(&cmd_client, "locs_reload", CL_Locs_Reload_f, "reload .loc file for this map");
Cmd_AddCommand(&cmd_client, "locs_save", CL_Locs_Save_f, "save .loc file for this map containing currently defined points and boxes");
+ Cvar_RegisterVariable(&csqc_polygons_defaultmaterial_nocullface);
+
CL_Parse_Init();
CL_Particles_Init();
CL_Screen_Init();
// we need to remember whether this is a 2D or 3D mesh we're adding to
mod = draw2d ? CL_Mesh_UI() : CL_Mesh_Scene();
prog->polygonbegin_model = mod;
+ if (texname == NULL || texname[0] == 0)
+ texname = "$whiteimage";
strlcpy(prog->polygonbegin_texname, texname, sizeof(prog->polygonbegin_texname));
prog->polygonbegin_drawflags = drawflags;
prog->polygonbegin_numvertices = 0;
float *o;
dp_model_t *mod = prog->polygonbegin_model;
msurface_t *surf;
+ texture_t *tex;
+ int materialflags;
VM_SAFEPARMCOUNT(0, VM_CL_R_PolygonEnd);
if (!mod)
}
// create the surface, looking up the best matching texture/shader
- surf = Mod_Mesh_AddSurface(mod, Mod_Mesh_GetTexture(mod, prog->polygonbegin_texname, prog->polygonbegin_drawflags, TEXF_ALPHA, MATERIALFLAG_WALL | (hascolor ? MATERIALFLAG_VERTEXCOLOR : 0) | (hasalpha ? MATERIALFLAG_ALPHAGEN_VERTEX | MATERIALFLAG_ALPHA | MATERIALFLAG_BLENDED | MATERIALFLAG_NOSHADOW : 0)), false);
+ materialflags = MATERIALFLAG_WALL;
+ if (csqc_polygons_defaultmaterial_nocullface.integer)
+ materialflags |= MATERIALFLAG_NOCULLFACE;
+ if (hascolor)
+ materialflags |= MATERIALFLAG_VERTEXCOLOR;
+ if (hasalpha)
+ materialflags |= MATERIALFLAG_ALPHAGEN_VERTEX | MATERIALFLAG_ALPHA | MATERIALFLAG_BLENDED | MATERIALFLAG_NOSHADOW;
+ tex = Mod_Mesh_GetTexture(mod, prog->polygonbegin_texname, prog->polygonbegin_drawflags, TEXF_ALPHA, materialflags);
+ surf = Mod_Mesh_AddSurface(mod, tex, false);
// create triangle fan
for (i = 0; i < prog->polygonbegin_numvertices; i++)
{
"sys_ticrate 0.01388889\n"
"r_shadow_gloss 1\n"
"r_shadow_bumpscale_basetexture 0\n"
+"csqc_polygons_defaultmaterial_nocullface 0\n"
);
break;
case GAME_NEHAHRA:
"sys_ticrate 0.01388889\n"
"r_shadow_gloss 1\n"
"r_shadow_bumpscale_basetexture 0\n"
+"csqc_polygons_defaultmaterial_nocullface 0\n"
);
break;
// hipnotic mission pack has issues in their 'friendly monster' ai, which seem to attempt to attack themselves for some reason when findradius() returns non-solid entities.
"sys_ticrate 0.02\n"
"r_shadow_gloss 1\n"
"r_shadow_bumpscale_basetexture 0\n"
+"csqc_polygons_defaultmaterial_nocullface 0\n"
);
break;
// rogue mission pack has a guardian boss that does not wake up if findradius returns one of the entities around its spawn area
"sys_ticrate 0.01388889\n"
"r_shadow_gloss 1\n"
"r_shadow_bumpscale_basetexture 0\n"
+"csqc_polygons_defaultmaterial_nocullface 0\n"
);
break;
case GAME_TENEBRAE:
"sys_ticrate 0.01388889\n"
"r_shadow_gloss 2\n"
"r_shadow_bumpscale_basetexture 4\n"
+"csqc_polygons_defaultmaterial_nocullface 0\n"
);
break;
case GAME_NEXUIZ:
"sys_ticrate 0.01388889\n"
"sv_gameplayfix_q2airaccelerate 1\n"
"sv_gameplayfix_stepmultipletimes 1\n"
+"csqc_polygons_defaultmaterial_nocullface 1\n"
+ );
+ break;
+ case GAME_XONOTIC:
+ case GAME_VORETOURNAMENT:
+ // compatibility for versions prior to 2020-05-25, this can be overridden in newer versions to get the default behavior and be consistent with FTEQW engine
+ Cbuf_InsertText(cmd, "\n"
+"csqc_polygons_defaultmaterial_nocullface 1\n"
);
break;
// Steel Storm: Burning Retribution csqc misinterprets CSQC_InputEvent if type is a value other than 0 or 1
"sv_gameplayfix_downtracesupportsongroundflag 1\n"
"sys_ticrate 0.01388889\n"
"cl_csqc_generatemousemoveevents 0\n"
+"csqc_polygons_defaultmaterial_nocullface 1\n"
);
break;
default:
"sv_gameplayfix_swiminbmodels 1\n"
"sv_gameplayfix_downtracesupportsongroundflag 1\n"
"sys_ticrate 0.01388889\n"
+"csqc_polygons_defaultmaterial_nocullface 0\n"
);
break;
}
extern cvar_t csqc_progname; //[515]: csqc crc check and right csprogs name according to progs.dat
extern cvar_t csqc_progcrc;
extern cvar_t csqc_progsize;
+extern cvar_t csqc_polygons_defaultmaterial_nocullface;
void CL_VM_PreventInformationLeaks(void);
void Mod_Mesh_Create(dp_model_t *mod, const char *name);
void Mod_Mesh_Destroy(dp_model_t *mod);
void Mod_Mesh_Reset(dp_model_t *mod);
-texture_t *Mod_Mesh_GetTexture(dp_model_t *mod, const char *name, int defaultdrawflags, int defaulttexflags, int addmaterialflags);
+texture_t *Mod_Mesh_GetTexture(dp_model_t *mod, const char *name, int defaultdrawflags, int defaulttexflags, int defaultmaterialflags);
msurface_t *Mod_Mesh_AddSurface(dp_model_t *mod, texture_t *tex, qboolean batchwithprevioussurface);
int Mod_Mesh_IndexForVertex(dp_model_t *mod, msurface_t *surf, float x, float y, float z, float nx, float ny, float nz, float s, float t, float u, float v, float r, float g, float b, float a);
void Mod_Mesh_AddTriangle(dp_model_t *mod, msurface_t *surf, int e0, int e1, int e2);