From: havoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Date: Fri, 25 May 2007 20:32:05 +0000 (+0000)
Subject: reorganized rgbgen/alphagen/tcgen fields into their own structs to clean
X-Git-Tag: xonotic-v0.1.0preview~3091
X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=97cdef0adb81c4401dcb9cfa292a3eb386214dac;p=xonotic%2Fdarkplaces.git

reorganized rgbgen/alphagen/tcgen fields into their own structs to clean
up the code somewhat


git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@7369 d7cf8633-e32d-0410-b094-e92efae38249
---

diff --git a/gl_rmain.c b/gl_rmain.c
index 8e46d7be..3c23d277 100644
--- a/gl_rmain.c
+++ b/gl_rmain.c
@@ -3177,6 +3177,7 @@ void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t)
 	model_t *model = ent->model;
 	float f;
 	float tcmat[12];
+	q3shaderinfo_layer_tcmod_t *tcmod;
 
 	// switch to an alternate material if this is a q1bsp animated material
 	{
@@ -3242,10 +3243,10 @@ void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t)
 	if (t->backgroundnumskinframes && !(t->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED))
 		t->currentmaterialflags |= MATERIALFLAG_VERTEXTEXTUREBLEND;
 
-	for (i = 0;i < Q3MAXTCMODS && (t->tcmod[i] || i < 1);i++)
+	for (i = 0, tcmod = t->tcmods;i < Q3MAXTCMODS && (tcmod->tcmod || i < 1);i++, tcmod++)
 	{
 		matrix4x4_t matrix;
-		switch(t->tcmod[i])
+		switch(tcmod->tcmod)
 		{
 		case Q3TCMOD_COUNT:
 		case Q3TCMOD_NONE:
@@ -3261,24 +3262,24 @@ void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t)
 			break;
 		case Q3TCMOD_ROTATE:
 			Matrix4x4_CreateTranslate(&matrix, 0.5, 0.5, 0);
-			Matrix4x4_ConcatRotate(&matrix, t->tcmod_parms[i][0] * r_refdef.time, 0, 0, 1);
+			Matrix4x4_ConcatRotate(&matrix, tcmod->parms[0] * r_refdef.time, 0, 0, 1);
 			Matrix4x4_ConcatTranslate(&matrix, -0.5, -0.5, 0);
 			break;
 		case Q3TCMOD_SCALE:
-			Matrix4x4_CreateScale3(&matrix, t->tcmod_parms[i][0], t->tcmod_parms[i][1], 1);
+			Matrix4x4_CreateScale3(&matrix, tcmod->parms[0], tcmod->parms[1], 1);
 			break;
 		case Q3TCMOD_SCROLL:
-			Matrix4x4_CreateTranslate(&matrix, t->tcmod_parms[i][0] * r_refdef.time, t->tcmod_parms[i][1] * r_refdef.time, 0);
+			Matrix4x4_CreateTranslate(&matrix, tcmod->parms[0] * r_refdef.time, tcmod->parms[1] * r_refdef.time, 0);
 			break;
 		case Q3TCMOD_STRETCH:
-			f = 1.0f / R_EvaluateQ3WaveFunc(t->tcmod_wavefunc[i], t->tcmod_parms[i]);
+			f = 1.0f / R_EvaluateQ3WaveFunc(tcmod->wavefunc, tcmod->waveparms);
 			Matrix4x4_CreateFromQuakeEntity(&matrix, 0.5f * (1 - f), 0.5 * (1 - f), 0, 0, 0, 0, f);
 			break;
 		case Q3TCMOD_TRANSFORM:
-			VectorSet(tcmat +  0, t->tcmod_parms[i][0], t->tcmod_parms[i][1], 0);
-			VectorSet(tcmat +  3, t->tcmod_parms[i][2], t->tcmod_parms[i][3], 0);
+			VectorSet(tcmat +  0, tcmod->parms[0], tcmod->parms[1], 0);
+			VectorSet(tcmat +  3, tcmod->parms[2], tcmod->parms[3], 0);
 			VectorSet(tcmat +  6, 0                   , 0                , 1);
-			VectorSet(tcmat +  9, t->tcmod_parms[i][4], t->tcmod_parms[i][5], 0);
+			VectorSet(tcmat +  9, tcmod->parms[4], tcmod->parms[5], 0);
 			Matrix4x4_FromArray12FloatGL(&matrix, tcmat);
 			break;
 		case Q3TCMOD_TURBULENT:
@@ -3639,7 +3640,7 @@ void RSurf_PrepareVerticesForBatch(qboolean generatenormals, qboolean generateta
 	// if vertices are dynamic (animated models), generate them into the temporary rsurface.array_model* arrays and point rsurface.model* at them instead of the static data from the model itself
 	if (rsurface.generatedvertex)
 	{
-		if (rsurface.texture->tcgen == Q3TCGEN_ENVIRONMENT)
+		if (rsurface.texture->tcgen.tcgen == Q3TCGEN_ENVIRONMENT)
 			generatenormals = true;
 		for (i = 0;i < Q3MAXDEFORMS;i++)
 		{
@@ -3853,9 +3854,9 @@ void RSurf_PrepareVerticesForBatch(qboolean generatenormals, qboolean generateta
 					float *normal = (rsurface.array_deformednormal3f  + 3 * surface->num_firstvertex) + j*3;
 					VectorScale((rsurface.vertex3f  + 3 * surface->num_firstvertex) + j*3, 0.98f, vertex);
 					VectorCopy((rsurface.normal3f  + 3 * surface->num_firstvertex) + j*3, normal);
-					normal[0] += deform->deform_parms[0] * noise4f(      vertex[0], vertex[1], vertex[2], r_refdef.time * deform->deform_parms[1]);
-					normal[1] += deform->deform_parms[0] * noise4f( 98 + vertex[0], vertex[1], vertex[2], r_refdef.time * deform->deform_parms[1]);
-					normal[2] += deform->deform_parms[0] * noise4f(196 + vertex[0], vertex[1], vertex[2], r_refdef.time * deform->deform_parms[1]);
+					normal[0] += deform->parms[0] * noise4f(      vertex[0], vertex[1], vertex[2], r_refdef.time * deform->parms[1]);
+					normal[1] += deform->parms[0] * noise4f( 98 + vertex[0], vertex[1], vertex[2], r_refdef.time * deform->parms[1]);
+					normal[2] += deform->parms[0] * noise4f(196 + vertex[0], vertex[1], vertex[2], r_refdef.time * deform->parms[1]);
 					VectorNormalize(normal);
 				}
 				Mod_BuildTextureVectorsFromNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, rsurface.vertex3f, rsurface.modeltexcoordtexture2f, rsurface.array_deformednormal3f, rsurface.modelelement3i + surface->num_firsttriangle * 3, rsurface.array_deformedsvector3f, rsurface.array_deformedtvector3f, r_smoothnormals_areaweighting.integer);
@@ -3872,13 +3873,13 @@ void RSurf_PrepareVerticesForBatch(qboolean generatenormals, qboolean generateta
 			break;
 		case Q3DEFORM_WAVE:
 			// deform vertex array to make wavey water and flags and such
-			waveparms[0] = deform->deform_waveparms[0];
-			waveparms[1] = deform->deform_waveparms[1];
-			waveparms[2] = deform->deform_waveparms[2];
-			waveparms[3] = deform->deform_waveparms[3];
+			waveparms[0] = deform->waveparms[0];
+			waveparms[1] = deform->waveparms[1];
+			waveparms[2] = deform->waveparms[2];
+			waveparms[3] = deform->waveparms[3];
 			// this is how a divisor of vertex influence on deformation
-			animpos = deform->deform_parms[0] ? 1.0f / deform->deform_parms[0] : 100.0f;
-			scale = R_EvaluateQ3WaveFunc(deform->deform_wavefunc, waveparms);
+			animpos = deform->parms[0] ? 1.0f / deform->parms[0] : 100.0f;
+			scale = R_EvaluateQ3WaveFunc(deform->wavefunc, waveparms);
 			for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
 			{
 				const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
@@ -3889,8 +3890,8 @@ void RSurf_PrepareVerticesForBatch(qboolean generatenormals, qboolean generateta
 					// if the wavefunc depends on time, evaluate it per-vertex
 					if (waveparms[3])
 					{
-						waveparms[2] = deform->deform_waveparms[2] + (vertex[0] + vertex[1] + vertex[2]) * animpos;
-						scale = R_EvaluateQ3WaveFunc(deform->deform_wavefunc, waveparms);
+						waveparms[2] = deform->waveparms[2] + (vertex[0] + vertex[1] + vertex[2]) * animpos;
+						scale = R_EvaluateQ3WaveFunc(deform->wavefunc, waveparms);
 					}
 					VectorMA(vertex, scale, (rsurface.normal3f  + 3 * surface->num_firstvertex) + j*3, vertex);
 				}
@@ -3906,7 +3907,7 @@ void RSurf_PrepareVerticesForBatch(qboolean generatenormals, qboolean generateta
 				const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
 				for (j = 0;j < surface->num_vertices;j++)
 				{
-					scale = sin((rsurface.modeltexcoordtexture2f[2 * (surface->num_firstvertex + j)] * deform->deform_parms[0] + r_refdef.time * deform->deform_parms[2])) * deform->deform_parms[1];
+					scale = sin((rsurface.modeltexcoordtexture2f[2 * (surface->num_firstvertex + j)] * deform->parms[0] + r_refdef.time * deform->parms[2])) * deform->parms[1];
 					VectorMA(rsurface.vertex3f + 3 * (surface->num_firstvertex + j), scale, rsurface.normal3f + 3 * (surface->num_firstvertex + j), rsurface.array_deformedvertex3f + 3 * (surface->num_firstvertex + j));
 				}
 			}
@@ -3916,8 +3917,8 @@ void RSurf_PrepareVerticesForBatch(qboolean generatenormals, qboolean generateta
 			break;
 		case Q3DEFORM_MOVE:
 			// deform vertex array
-			scale = R_EvaluateQ3WaveFunc(deform->deform_wavefunc, deform->deform_waveparms);
-			VectorScale(deform->deform_parms, scale, waveparms);
+			scale = R_EvaluateQ3WaveFunc(deform->wavefunc, deform->waveparms);
+			VectorScale(deform->parms, scale, waveparms);
 			for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
 			{
 				const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
@@ -3931,7 +3932,7 @@ void RSurf_PrepareVerticesForBatch(qboolean generatenormals, qboolean generateta
 		}
 	}
 	// generate texcoords based on the chosen texcoord source
-	switch(rsurface.texture->tcgen)
+	switch(rsurface.texture->tcgen.tcgen)
 	{
 	default:
 	case Q3TCGEN_TEXTURE:
@@ -3950,8 +3951,8 @@ void RSurf_PrepareVerticesForBatch(qboolean generatenormals, qboolean generateta
 			const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
 			for (j = 0, v1 = rsurface.modelvertex3f + 3 * surface->num_firstvertex, out_tc = rsurface.array_generatedtexcoordtexture2f + 2 * surface->num_firstvertex;j < surface->num_vertices;j++, v1 += 3, out_tc += 2)
 			{
-				out_tc[0] = DotProduct(v1, rsurface.texture->tcgen_parms);
-				out_tc[1] = DotProduct(v1, rsurface.texture->tcgen_parms + 3);
+				out_tc[0] = DotProduct(v1, rsurface.texture->tcgen.parms);
+				out_tc[1] = DotProduct(v1, rsurface.texture->tcgen.parms + 3);
 			}
 		}
 		rsurface.texcoordtexture2f               = rsurface.array_generatedtexcoordtexture2f;
@@ -3986,10 +3987,10 @@ void RSurf_PrepareVerticesForBatch(qboolean generatenormals, qboolean generateta
 	// and we only support that as the first one
 	// (handling a mixture of turbulent and other tcmods would be problematic
 	//  without punting it entirely to a software path)
-	if (rsurface.texture->tcmod[0] == Q3TCMOD_TURBULENT)
+	if (rsurface.texture->tcmods[0].tcmod == Q3TCMOD_TURBULENT)
 	{
-		amplitude = rsurface.texture->tcmod_parms[0][1];
-		animpos = rsurface.texture->tcmod_parms[0][2] + r_refdef.time * rsurface.texture->tcmod_parms[0][3];
+		amplitude = rsurface.texture->tcmods[0].parms[1];
+		animpos = rsurface.texture->tcmods[0].parms[2] + r_refdef.time * rsurface.texture->tcmods[0].parms[3];
 		for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
 		{
 			const msurface_t *surface = texturesurfacelist[texturesurfaceindex];
diff --git a/model_shared.c b/model_shared.c
index 371d135e..a9b7486c 100644
--- a/model_shared.c
+++ b/model_shared.c
@@ -1149,9 +1149,9 @@ void Mod_LoadQ3Shaders(void)
 					if (shader->numlayers < Q3SHADER_MAXLAYERS)
 					{
 						layer = shader->layers + shader->numlayers++;
-						layer->rgbgen = Q3RGBGEN_IDENTITY;
-						layer->alphagen = Q3ALPHAGEN_IDENTITY;
-						layer->tcgen = Q3TCGEN_TEXTURE;
+						layer->rgbgen.rgbgen = Q3RGBGEN_IDENTITY;
+						layer->alphagen.alphagen = Q3ALPHAGEN_IDENTITY;
+						layer->tcgen.tcgen = Q3TCGEN_TEXTURE;
 						layer->blendfunc[0] = GL_ONE;
 						layer->blendfunc[1] = GL_ZERO;
 					}
@@ -1259,22 +1259,22 @@ void Mod_LoadQ3Shaders(void)
 						{
 							int i;
 							for (i = 0;i < numparameters - 2 && i < Q3RGBGEN_MAXPARMS;i++)
-								layer->rgbgen_parms[i] = atof(parameter[i+2]);
-							     if (!strcasecmp(parameter[1], "identity"))         layer->rgbgen = Q3RGBGEN_IDENTITY;
-							else if (!strcasecmp(parameter[1], "const"))            layer->rgbgen = Q3RGBGEN_CONST;
-							else if (!strcasecmp(parameter[1], "entity"))           layer->rgbgen = Q3RGBGEN_ENTITY;
-							else if (!strcasecmp(parameter[1], "exactvertex"))      layer->rgbgen = Q3RGBGEN_EXACTVERTEX;
-							else if (!strcasecmp(parameter[1], "identitylighting")) layer->rgbgen = Q3RGBGEN_IDENTITYLIGHTING;
-							else if (!strcasecmp(parameter[1], "lightingdiffuse"))  layer->rgbgen = Q3RGBGEN_LIGHTINGDIFFUSE;
-							else if (!strcasecmp(parameter[1], "oneminusentity"))   layer->rgbgen = Q3RGBGEN_ONEMINUSENTITY;
-							else if (!strcasecmp(parameter[1], "oneminusvertex"))   layer->rgbgen = Q3RGBGEN_ONEMINUSVERTEX;
-							else if (!strcasecmp(parameter[1], "vertex"))           layer->rgbgen = Q3RGBGEN_VERTEX;
+								layer->rgbgen.parms[i] = atof(parameter[i+2]);
+							     if (!strcasecmp(parameter[1], "identity"))         layer->rgbgen.rgbgen = Q3RGBGEN_IDENTITY;
+							else if (!strcasecmp(parameter[1], "const"))            layer->rgbgen.rgbgen = Q3RGBGEN_CONST;
+							else if (!strcasecmp(parameter[1], "entity"))           layer->rgbgen.rgbgen = Q3RGBGEN_ENTITY;
+							else if (!strcasecmp(parameter[1], "exactvertex"))      layer->rgbgen.rgbgen = Q3RGBGEN_EXACTVERTEX;
+							else if (!strcasecmp(parameter[1], "identitylighting")) layer->rgbgen.rgbgen = Q3RGBGEN_IDENTITYLIGHTING;
+							else if (!strcasecmp(parameter[1], "lightingdiffuse"))  layer->rgbgen.rgbgen = Q3RGBGEN_LIGHTINGDIFFUSE;
+							else if (!strcasecmp(parameter[1], "oneminusentity"))   layer->rgbgen.rgbgen = Q3RGBGEN_ONEMINUSENTITY;
+							else if (!strcasecmp(parameter[1], "oneminusvertex"))   layer->rgbgen.rgbgen = Q3RGBGEN_ONEMINUSVERTEX;
+							else if (!strcasecmp(parameter[1], "vertex"))           layer->rgbgen.rgbgen = Q3RGBGEN_VERTEX;
 							else if (!strcasecmp(parameter[1], "wave"))
 							{
-								layer->rgbgen = Q3RGBGEN_WAVE;
-								layer->rgbgen_wavefunc = Mod_LoadQ3Shaders_EnumerateWaveFunc(parameter[2]);
+								layer->rgbgen.rgbgen = Q3RGBGEN_WAVE;
+								layer->rgbgen.wavefunc = Mod_LoadQ3Shaders_EnumerateWaveFunc(parameter[2]);
 								for (i = 0;i < numparameters - 3 && i < Q3WAVEPARMS;i++)
-									layer->rgbgen_waveparms[i] = atof(parameter[i+3]);
+									layer->rgbgen.waveparms[i] = atof(parameter[i+3]);
 							}
 							else Con_DPrintf("%s parsing warning: unknown rgbgen %s\n", search->filenames[fileindex], parameter[1]);
 						}
@@ -1282,21 +1282,21 @@ void Mod_LoadQ3Shaders(void)
 						{
 							int i;
 							for (i = 0;i < numparameters - 2 && i < Q3ALPHAGEN_MAXPARMS;i++)
-								layer->alphagen_parms[i] = atof(parameter[i+2]);
-							     if (!strcasecmp(parameter[1], "identity"))         layer->alphagen = Q3ALPHAGEN_IDENTITY;
-							else if (!strcasecmp(parameter[1], "const"))            layer->alphagen = Q3ALPHAGEN_CONST;
-							else if (!strcasecmp(parameter[1], "entity"))           layer->alphagen = Q3ALPHAGEN_ENTITY;
-							else if (!strcasecmp(parameter[1], "lightingspecular")) layer->alphagen = Q3ALPHAGEN_LIGHTINGSPECULAR;
-							else if (!strcasecmp(parameter[1], "oneminusentity"))   layer->alphagen = Q3ALPHAGEN_ONEMINUSENTITY;
-							else if (!strcasecmp(parameter[1], "oneminusvertex"))   layer->alphagen = Q3ALPHAGEN_ONEMINUSVERTEX;
-							else if (!strcasecmp(parameter[1], "portal"))           layer->alphagen = Q3ALPHAGEN_PORTAL;
-							else if (!strcasecmp(parameter[1], "vertex"))           layer->alphagen = Q3ALPHAGEN_VERTEX;
+								layer->alphagen.parms[i] = atof(parameter[i+2]);
+							     if (!strcasecmp(parameter[1], "identity"))         layer->alphagen.alphagen = Q3ALPHAGEN_IDENTITY;
+							else if (!strcasecmp(parameter[1], "const"))            layer->alphagen.alphagen = Q3ALPHAGEN_CONST;
+							else if (!strcasecmp(parameter[1], "entity"))           layer->alphagen.alphagen = Q3ALPHAGEN_ENTITY;
+							else if (!strcasecmp(parameter[1], "lightingspecular")) layer->alphagen.alphagen = Q3ALPHAGEN_LIGHTINGSPECULAR;
+							else if (!strcasecmp(parameter[1], "oneminusentity"))   layer->alphagen.alphagen = Q3ALPHAGEN_ONEMINUSENTITY;
+							else if (!strcasecmp(parameter[1], "oneminusvertex"))   layer->alphagen.alphagen = Q3ALPHAGEN_ONEMINUSVERTEX;
+							else if (!strcasecmp(parameter[1], "portal"))           layer->alphagen.alphagen = Q3ALPHAGEN_PORTAL;
+							else if (!strcasecmp(parameter[1], "vertex"))           layer->alphagen.alphagen = Q3ALPHAGEN_VERTEX;
 							else if (!strcasecmp(parameter[1], "wave"))
 							{
-								layer->alphagen = Q3RGBGEN_WAVE;
-								layer->alphagen_wavefunc = Mod_LoadQ3Shaders_EnumerateWaveFunc(parameter[2]);
+								layer->alphagen.alphagen = Q3RGBGEN_WAVE;
+								layer->alphagen.wavefunc = Mod_LoadQ3Shaders_EnumerateWaveFunc(parameter[2]);
 								for (i = 0;i < numparameters - 3 && i < Q3WAVEPARMS;i++)
-									layer->alphagen_waveparms[i] = atof(parameter[i+3]);
+									layer->alphagen.waveparms[i] = atof(parameter[i+3]);
 							}
 							else Con_DPrintf("%s parsing warning: unknown alphagen %s\n", search->filenames[fileindex], parameter[1]);
 						}
@@ -1306,12 +1306,12 @@ void Mod_LoadQ3Shaders(void)
 							// observed values: tcgen environment
 							// no other values have been observed in real shaders
 							for (i = 0;i < numparameters - 2 && i < Q3TCGEN_MAXPARMS;i++)
-								layer->tcgen_parms[i] = atof(parameter[i+2]);
-							     if (!strcasecmp(parameter[1], "base"))        layer->tcgen = Q3TCGEN_TEXTURE;
-							else if (!strcasecmp(parameter[1], "texture"))     layer->tcgen = Q3TCGEN_TEXTURE;
-							else if (!strcasecmp(parameter[1], "environment")) layer->tcgen = Q3TCGEN_ENVIRONMENT;
-							else if (!strcasecmp(parameter[1], "lightmap"))    layer->tcgen = Q3TCGEN_LIGHTMAP;
-							else if (!strcasecmp(parameter[1], "vector"))      layer->tcgen = Q3TCGEN_VECTOR;
+								layer->tcgen.parms[i] = atof(parameter[i+2]);
+							     if (!strcasecmp(parameter[1], "base"))        layer->tcgen.tcgen = Q3TCGEN_TEXTURE;
+							else if (!strcasecmp(parameter[1], "texture"))     layer->tcgen.tcgen = Q3TCGEN_TEXTURE;
+							else if (!strcasecmp(parameter[1], "environment")) layer->tcgen.tcgen = Q3TCGEN_ENVIRONMENT;
+							else if (!strcasecmp(parameter[1], "lightmap"))    layer->tcgen.tcgen = Q3TCGEN_LIGHTMAP;
+							else if (!strcasecmp(parameter[1], "vector"))      layer->tcgen.tcgen = Q3TCGEN_VECTOR;
 							else Con_DPrintf("%s parsing warning: unknown tcgen mode %s\n", search->filenames[fileindex], parameter[1]);
 						}
 						else if (numparameters >= 2 && !strcasecmp(parameter[0], "tcmod"))
@@ -1328,25 +1328,25 @@ void Mod_LoadQ3Shaders(void)
 							// tcmod turb sin # # # #  (this is bogus)
 							// no other values have been observed in real shaders
 							for (tcmodindex = 0;tcmodindex < Q3MAXTCMODS;tcmodindex++)
-								if (!layer->tcmod[tcmodindex])
+								if (!layer->tcmods[tcmodindex].tcmod)
 									break;
 							if (tcmodindex < Q3MAXTCMODS)
 							{
 								for (i = 0;i < numparameters - 2 && i < Q3TCMOD_MAXPARMS;i++)
-									layer->tcmod_parms[tcmodindex][i] = atof(parameter[i+2]);
-									 if (!strcasecmp(parameter[1], "entitytranslate")) layer->tcmod[tcmodindex] = Q3TCMOD_ENTITYTRANSLATE;
-								else if (!strcasecmp(parameter[1], "rotate"))          layer->tcmod[tcmodindex] = Q3TCMOD_ROTATE;
-								else if (!strcasecmp(parameter[1], "scale"))           layer->tcmod[tcmodindex] = Q3TCMOD_SCALE;
-								else if (!strcasecmp(parameter[1], "scroll"))          layer->tcmod[tcmodindex] = Q3TCMOD_SCROLL;
+									layer->tcmods[tcmodindex].parms[i] = atof(parameter[i+2]);
+									 if (!strcasecmp(parameter[1], "entitytranslate")) layer->tcmods[tcmodindex].tcmod = Q3TCMOD_ENTITYTRANSLATE;
+								else if (!strcasecmp(parameter[1], "rotate"))          layer->tcmods[tcmodindex].tcmod = Q3TCMOD_ROTATE;
+								else if (!strcasecmp(parameter[1], "scale"))           layer->tcmods[tcmodindex].tcmod = Q3TCMOD_SCALE;
+								else if (!strcasecmp(parameter[1], "scroll"))          layer->tcmods[tcmodindex].tcmod = Q3TCMOD_SCROLL;
 								else if (!strcasecmp(parameter[1], "stretch"))
 								{
-									layer->tcmod[tcmodindex] = Q3TCMOD_STRETCH;
-									layer->tcmod_wavefunc[tcmodindex] = Mod_LoadQ3Shaders_EnumerateWaveFunc(parameter[2]);
+									layer->tcmods[tcmodindex].tcmod = Q3TCMOD_STRETCH;
+									layer->tcmods[tcmodindex].wavefunc = Mod_LoadQ3Shaders_EnumerateWaveFunc(parameter[2]);
 									for (i = 0;i < numparameters - 3 && i < Q3WAVEPARMS;i++)
-										layer->tcmod_waveparms[tcmodindex][i] = atof(parameter[i+3]);
+										layer->tcmods[tcmodindex].waveparms[i] = atof(parameter[i+3]);
 								}
-								else if (!strcasecmp(parameter[1], "transform"))       layer->tcmod[tcmodindex] = Q3TCMOD_TRANSFORM;
-								else if (!strcasecmp(parameter[1], "turb"))            layer->tcmod[tcmodindex] = Q3TCMOD_TURBULENT;
+								else if (!strcasecmp(parameter[1], "transform"))       layer->tcmods[tcmodindex].tcmod = Q3TCMOD_TRANSFORM;
+								else if (!strcasecmp(parameter[1], "turb"))            layer->tcmods[tcmodindex].tcmod = Q3TCMOD_TURBULENT;
 								else Con_DPrintf("%s parsing warning: unknown tcmod mode %s\n", search->filenames[fileindex], parameter[1]);
 							}
 							else
@@ -1356,9 +1356,9 @@ void Mod_LoadQ3Shaders(void)
 						if (!strcasecmp(com_token, "}"))
 							break;
 					}
-					if (layer->rgbgen == Q3RGBGEN_LIGHTINGDIFFUSE || layer->rgbgen == Q3RGBGEN_VERTEX)
+					if (layer->rgbgen.rgbgen == Q3RGBGEN_LIGHTINGDIFFUSE || layer->rgbgen.rgbgen == Q3RGBGEN_VERTEX)
 						shader->lighting = true;
-					if (layer->alphagen == Q3ALPHAGEN_VERTEX)
+					if (layer->alphagen.alphagen == Q3ALPHAGEN_VERTEX)
 					{
 						if (layer == shader->layers + 0)
 						{
@@ -1497,7 +1497,7 @@ void Mod_LoadQ3Shaders(void)
 					if (deformindex < Q3MAXDEFORMS)
 					{
 						for (i = 0;i < numparameters - 2 && i < Q3DEFORM_MAXPARMS;i++)
-							shader->deforms[deformindex].deform_parms[i] = atof(parameter[i+2]);
+							shader->deforms[deformindex].parms[i] = atof(parameter[i+2]);
 						     if (!strcasecmp(parameter[1], "projectionshadow")) shader->deforms[deformindex].deform = Q3DEFORM_PROJECTIONSHADOW;
 						else if (!strcasecmp(parameter[1], "autosprite"      )) shader->deforms[deformindex].deform = Q3DEFORM_AUTOSPRITE;
 						else if (!strcasecmp(parameter[1], "autosprite2"     )) shader->deforms[deformindex].deform = Q3DEFORM_AUTOSPRITE2;
@@ -1514,16 +1514,16 @@ void Mod_LoadQ3Shaders(void)
 						else if (!strcasecmp(parameter[1], "wave"            ))
 						{
 							shader->deforms[deformindex].deform = Q3DEFORM_WAVE;
-							shader->deforms[deformindex].deform_wavefunc = Mod_LoadQ3Shaders_EnumerateWaveFunc(parameter[3]);
+							shader->deforms[deformindex].wavefunc = Mod_LoadQ3Shaders_EnumerateWaveFunc(parameter[3]);
 							for (i = 0;i < numparameters - 4 && i < Q3WAVEPARMS;i++)
-								shader->deforms[deformindex].deform_waveparms[i] = atof(parameter[i+4]);
+								shader->deforms[deformindex].waveparms[i] = atof(parameter[i+4]);
 						}
 						else if (!strcasecmp(parameter[1], "move"            ))
 						{
 							shader->deforms[deformindex].deform = Q3DEFORM_MOVE;
-							shader->deforms[deformindex].deform_wavefunc = Mod_LoadQ3Shaders_EnumerateWaveFunc(parameter[5]);
+							shader->deforms[deformindex].wavefunc = Mod_LoadQ3Shaders_EnumerateWaveFunc(parameter[5]);
 							for (i = 0;i < numparameters - 6 && i < Q3WAVEPARMS;i++)
-								shader->deforms[deformindex].deform_waveparms[i] = atof(parameter[i+6]);
+								shader->deforms[deformindex].waveparms[i] = atof(parameter[i+6]);
 						}
 					}
 				}
@@ -1643,20 +1643,10 @@ nothing                GL_ZERO GL_ONE
 		if (shader->primarylayer)
 		{
 			// copy over many shader->primarylayer parameters
-			texture->rgbgen   = shader->primarylayer->rgbgen;
-			memcpy(texture->rgbgen_parms      , shader->primarylayer->rgbgen_parms      , sizeof(texture->rgbgen_parms));
-			texture->rgbgen_wavefunc = shader->primarylayer->rgbgen_wavefunc;
-			memcpy(texture->rgbgen_waveparms  , shader->primarylayer->rgbgen_waveparms  , sizeof(texture->rgbgen_waveparms));
+			texture->rgbgen = shader->primarylayer->rgbgen;
 			texture->alphagen = shader->primarylayer->alphagen;
-			memcpy(texture->alphagen_parms    , shader->primarylayer->alphagen_parms    , sizeof(texture->alphagen_parms));
-			texture->alphagen_wavefunc = shader->primarylayer->alphagen_wavefunc;
-			memcpy(texture->alphagen_waveparms, shader->primarylayer->alphagen_waveparms, sizeof(texture->alphagen_waveparms));
-			texture->tcgen    = shader->primarylayer->tcgen;
-			memcpy(texture->tcgen_parms       , shader->primarylayer->tcgen_parms       , sizeof(texture->tcgen_parms));
-			memcpy(texture->tcmod             , shader->primarylayer->tcmod             , sizeof(texture->tcmod));
-			memcpy(texture->tcmod_parms       , shader->primarylayer->tcmod_parms       , sizeof(texture->tcmod_parms));
-			memcpy(texture->tcmod_wavefunc    , shader->primarylayer->tcmod_wavefunc    , sizeof(texture->tcmod_wavefunc));
-			memcpy(texture->tcmod_waveparms   , shader->primarylayer->tcmod_waveparms   , sizeof(texture->tcmod_waveparms));
+			texture->tcgen = shader->primarylayer->tcgen;
+			memcpy(texture->tcmods, shader->primarylayer->tcmods, sizeof(texture->tcmods));
 			// load the textures
 			texture->numskinframes = shader->primarylayer->numframes;
 			texture->skinframerate = shader->primarylayer->framerate;
diff --git a/model_shared.h b/model_shared.h
index 571dcc65..0773c3d1 100644
--- a/model_shared.h
+++ b/model_shared.h
@@ -290,6 +290,40 @@ typedef enum q3tcmod_e
 }
 q3tcmod_t;
 
+typedef struct q3shaderinfo_layer_rgbgen_s
+{
+	q3rgbgen_t rgbgen;
+	float parms[Q3RGBGEN_MAXPARMS];
+	q3wavefunc_t wavefunc;
+	float waveparms[Q3WAVEPARMS];
+}
+q3shaderinfo_layer_rgbgen_t;
+
+typedef struct q3shaderinfo_layer_alphagen_s
+{
+	q3alphagen_t alphagen;
+	float parms[Q3ALPHAGEN_MAXPARMS];
+	q3wavefunc_t wavefunc;
+	float waveparms[Q3WAVEPARMS];
+}
+q3shaderinfo_layer_alphagen_t;
+
+typedef struct q3shaderinfo_layer_tcgen_s
+{
+	q3tcgen_t tcgen;
+	float parms[Q3TCGEN_MAXPARMS];
+}
+q3shaderinfo_layer_tcgen_t;
+
+typedef struct q3shaderinfo_layer_tcmod_s
+{
+	q3tcmod_t tcmod;
+	float parms[Q3TCMOD_MAXPARMS];
+	q3wavefunc_t wavefunc;
+	float waveparms[Q3WAVEPARMS];
+}
+q3shaderinfo_layer_tcmod_t;
+
 typedef struct q3shaderinfo_layer_s
 {
 	int alphatest;
@@ -298,29 +332,19 @@ typedef struct q3shaderinfo_layer_s
 	int numframes;
 	char texturename[TEXTURE_MAXFRAMES][Q3PATHLENGTH];
 	int blendfunc[2];
-	q3rgbgen_t rgbgen;
-	float rgbgen_parms[Q3RGBGEN_MAXPARMS];
-	q3wavefunc_t rgbgen_wavefunc;
-	float rgbgen_waveparms[Q3WAVEPARMS];
-	q3alphagen_t alphagen;
-	float alphagen_parms[Q3ALPHAGEN_MAXPARMS];
-	q3wavefunc_t alphagen_wavefunc;
-	float alphagen_waveparms[Q3WAVEPARMS];
-	q3tcgen_t tcgen;
-	float tcgen_parms[Q3TCGEN_MAXPARMS];
-	q3tcmod_t tcmod[Q3MAXTCMODS];
-	float tcmod_parms[Q3MAXTCMODS][Q3TCMOD_MAXPARMS];
-	q3wavefunc_t tcmod_wavefunc[Q3MAXTCMODS];
-	float tcmod_waveparms[Q3MAXTCMODS][Q3WAVEPARMS];
+	q3shaderinfo_layer_rgbgen_t rgbgen;
+	q3shaderinfo_layer_alphagen_t alphagen;
+	q3shaderinfo_layer_tcgen_t tcgen;
+	q3shaderinfo_layer_tcmod_t tcmods[Q3MAXTCMODS];
 }
 q3shaderinfo_layer_t;
 
 typedef struct q3shaderinfo_deform_s
 {
 	q3deform_t deform;
-	float deform_parms[Q3DEFORM_MAXPARMS];
-	q3wavefunc_t deform_wavefunc;
-	float deform_waveparms[Q3WAVEPARMS];
+	float parms[Q3DEFORM_MAXPARMS];
+	q3wavefunc_t wavefunc;
+	float waveparms[Q3WAVEPARMS];
 }
 q3shaderinfo_deform_t;
 
@@ -415,25 +439,11 @@ typedef struct texture_s
 	matrix4x4_t currenttexmatrix;
 
 	// various q3 shader features
+	q3shaderinfo_layer_rgbgen_t rgbgen;
+	q3shaderinfo_layer_alphagen_t alphagen;
+	q3shaderinfo_layer_tcgen_t tcgen;
+	q3shaderinfo_layer_tcmod_t tcmods[Q3MAXTCMODS];
 	q3shaderinfo_deform_t deforms[Q3MAXDEFORMS];
-	q3deform_t deform;
-	float deform_parms[Q3DEFORM_MAXPARMS];
-	q3wavefunc_t deform_wavefunc;
-	float deform_waveparms[Q3WAVEPARMS];
-	q3rgbgen_t rgbgen;
-	float rgbgen_parms[Q3RGBGEN_MAXPARMS];
-	q3wavefunc_t rgbgen_wavefunc;
-	float rgbgen_waveparms[Q3WAVEPARMS];
-	q3alphagen_t alphagen;
-	float alphagen_parms[Q3ALPHAGEN_MAXPARMS];
-	q3wavefunc_t alphagen_wavefunc;
-	float alphagen_waveparms[Q3WAVEPARMS];
-	q3tcgen_t tcgen;
-	float tcgen_parms[Q3TCGEN_MAXPARMS];
-	q3tcmod_t tcmod[Q3MAXTCMODS];
-	float tcmod_parms[Q3MAXTCMODS][Q3TCMOD_MAXPARMS];
-	q3wavefunc_t tcmod_wavefunc[Q3MAXTCMODS];
-	float tcmod_waveparms[Q3MAXTCMODS][Q3WAVEPARMS];
 
 	qboolean colormapping;
 	rtexture_t *basetexture;