From 3291222c2c2c8cc53d63d859cf0f89940be25604 Mon Sep 17 00:00:00 2001
From: havoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Date: Mon, 25 May 2020 08:10:04 +0000
Subject: [PATCH] Add csqc_polygons_defaultmaterial_nocullface cvar which
 defaults to 1 in nexuiz and xonotic derived games, this restores the
 compatible behavior with older versions of the engine.  It defaults to 0 in
 other games (and would be recommended to set to 0 in those games when they
 make a new release) as it seems like that would be the better default for
 efficiency (and matches FTEQW engine).

Fixed a bug in CL_MeshEntities_FinalizeRenderEntity where it skipped finalize when the entity has no surfaces, but since it is still included in the render entities list it was rendering garbage when unused.

Use the "$whiteimage" texture for CSQC/UI polygons (VM_CL_R_PolygonBegin) that specify texture "", to be compatible with older versions.

Clarify the name of a parameter on Mod_Mesh_GetTexture prototype to match the implementation as it was misleading otherwise.



git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@12569 d7cf8633-e32d-0410-b094-e92efae38249
---
 cl_main.c      | 12 ++++++------
 clvm_cmds.c    | 14 +++++++++++++-
 cmd.c          | 15 +++++++++++++++
 csprogs.h      |  1 +
 model_shared.h |  2 +-
 5 files changed, 36 insertions(+), 8 deletions(-)

diff --git a/cl_main.c b/cl_main.c
index 210d35f5..e710a1ca 100644
--- a/cl_main.c
+++ b/cl_main.c
@@ -35,6 +35,7 @@ cvar_t csqc_progname = {CVAR_CLIENT | CVAR_SERVER, "csqc_progname","csprogs.dat"
 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"};
@@ -2442,12 +2443,9 @@ void CL_MeshEntities_Scene_AddRenderEntity(void)
 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)
@@ -2743,6 +2741,8 @@ void CL_Init (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();
diff --git a/clvm_cmds.c b/clvm_cmds.c
index efbae27c..d2836b37 100644
--- a/clvm_cmds.c
+++ b/clvm_cmds.c
@@ -3307,6 +3307,8 @@ static void VM_CL_R_PolygonBegin (prvm_prog_t *prog)
 	// 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;
@@ -3359,6 +3361,8 @@ static void VM_CL_R_PolygonEnd (prvm_prog_t *prog)
 	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)
@@ -3380,7 +3384,15 @@ static void VM_CL_R_PolygonEnd (prvm_prog_t *prog)
 	}
 
 	// 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++)
 	{
diff --git a/cmd.c b/cmd.c
index ce0c4013..d19e96fa 100644
--- a/cmd.c
+++ b/cmd.c
@@ -525,6 +525,7 @@ static void Cmd_Exec(cmd_state_t *cmd, const char *filename)
 "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:
@@ -549,6 +550,7 @@ static void Cmd_Exec(cmd_state_t *cmd, const char *filename)
 "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.
@@ -577,6 +579,7 @@ static void Cmd_Exec(cmd_state_t *cmd, const char *filename)
 "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
@@ -602,6 +605,7 @@ static void Cmd_Exec(cmd_state_t *cmd, const char *filename)
 "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:
@@ -626,6 +630,7 @@ static void Cmd_Exec(cmd_state_t *cmd, const char *filename)
 "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:
@@ -650,6 +655,14 @@ static void Cmd_Exec(cmd_state_t *cmd, const char *filename)
 "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
@@ -674,6 +687,7 @@ static void Cmd_Exec(cmd_state_t *cmd, const char *filename)
 "sv_gameplayfix_downtracesupportsongroundflag 1\n"
 "sys_ticrate 0.01388889\n"
 "cl_csqc_generatemousemoveevents 0\n"
+"csqc_polygons_defaultmaterial_nocullface 1\n"
 				);
 			break;
 		default:
@@ -696,6 +710,7 @@ static void Cmd_Exec(cmd_state_t *cmd, const char *filename)
 "sv_gameplayfix_swiminbmodels 1\n"
 "sv_gameplayfix_downtracesupportsongroundflag 1\n"
 "sys_ticrate 0.01388889\n"
+"csqc_polygons_defaultmaterial_nocullface 0\n"
 				);
 			break;
 		}
diff --git a/csprogs.h b/csprogs.h
index cfd721c0..dff44d74 100644
--- a/csprogs.h
+++ b/csprogs.h
@@ -76,6 +76,7 @@
 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);
 
diff --git a/model_shared.h b/model_shared.h
index db71e4b1..62bbd7dc 100644
--- a/model_shared.h
+++ b/model_shared.h
@@ -1215,7 +1215,7 @@ void R_Q1BSP_DrawLight(struct entity_render_s *ent, int numsurfaces, const int *
 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);
-- 
2.39.5