From d6941f91374ee93b2c98439505fd2dc7be050197 Mon Sep 17 00:00:00 2001 From: havoc Date: Thu, 24 May 2007 07:35:30 +0000 Subject: [PATCH] support multiple tcmod commands on a single layer git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@7364 d7cf8633-e32d-0410-b094-e92efae38249 --- gl_rmain.c | 97 +++++++++++++++++++++++++++++--------------------- model_shared.c | 43 ++++++++++++---------- model_shared.h | 13 +++---- 3 files changed, 88 insertions(+), 65 deletions(-) diff --git a/gl_rmain.c b/gl_rmain.c index 30b45979..373187a6 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -3242,46 +3242,58 @@ void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t) if (t->backgroundnumskinframes && !(t->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED)) t->currentmaterialflags |= MATERIALFLAG_VERTEXTEXTUREBLEND; - switch(t->tcmod) + for (i = 0;i < Q3MAXTCMODS && (t->tcmod[i] || i < 1);i++) { - case Q3TCMOD_COUNT: - case Q3TCMOD_NONE: - if (t->currentmaterialflags & MATERIALFLAG_WATER && r_waterscroll.value != 0) - t->currenttexmatrix = r_waterscrollmatrix; + matrix4x4_t matrix; + switch(t->tcmod[i]) + { + case Q3TCMOD_COUNT: + case Q3TCMOD_NONE: + if (t->currentmaterialflags & MATERIALFLAG_WATER && r_waterscroll.value != 0) + matrix = r_waterscrollmatrix; + else + matrix = identitymatrix; + break; + case Q3TCMOD_ENTITYTRANSLATE: + // this is used in Q3 to allow the gamecode to control texcoord + // scrolling on the entity, which is not supported in darkplaces yet. + Matrix4x4_CreateTranslate(&matrix, 0, 0, 0); + 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_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); + break; + case Q3TCMOD_SCROLL: + Matrix4x4_CreateTranslate(&matrix, t->tcmod_parms[i][0] * r_refdef.time, t->tcmod_parms[i][1] * r_refdef.time, 0); + break; + case Q3TCMOD_STRETCH: + f = 1.0f / R_EvaluateQ3WaveFunc(t->tcmod_wavefunc[i], t->tcmod_parms[i]); + 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 + 6, 0 , 0 , 1); + VectorSet(tcmat + 9, t->tcmod_parms[i][4], t->tcmod_parms[i][5], 0); + Matrix4x4_FromArray12FloatGL(&matrix, tcmat); + break; + case Q3TCMOD_TURBULENT: + // this is handled in the RSurf_PrepareVertices function + matrix = identitymatrix; + break; + } + // either replace or concatenate the transformation + if (i < 1) + t->currenttexmatrix = matrix; else - t->currenttexmatrix = identitymatrix; - break; - case Q3TCMOD_ENTITYTRANSLATE: - // this is used in Q3 to allow the gamecode to control texcoord - // scrolling on the entity, which is not supported in darkplaces yet. - Matrix4x4_CreateTranslate(&t->currenttexmatrix, 0, 0, 0); - break; - case Q3TCMOD_ROTATE: - Matrix4x4_CreateTranslate(&t->currenttexmatrix, 0.5, 0.5, 0); - Matrix4x4_ConcatRotate(&t->currenttexmatrix, t->tcmod_parms[0] * r_refdef.time, 0, 0, 1); - Matrix4x4_ConcatTranslate(&t->currenttexmatrix, -0.5, -0.5, 0); - break; - case Q3TCMOD_SCALE: - Matrix4x4_CreateScale3(&t->currenttexmatrix, t->tcmod_parms[0], t->tcmod_parms[1], 1); - break; - case Q3TCMOD_SCROLL: - Matrix4x4_CreateTranslate(&t->currenttexmatrix, t->tcmod_parms[0] * r_refdef.time, t->tcmod_parms[1] * r_refdef.time, 0); - break; - case Q3TCMOD_STRETCH: - f = 1.0f / R_EvaluateQ3WaveFunc(t->tcmod_wavefunc, t->tcmod_parms); - Matrix4x4_CreateFromQuakeEntity(&t->currenttexmatrix, 0.5f * (1 - f), 0.5 * (1 - f), 0, 0, 0, 0, f); - break; - case Q3TCMOD_TRANSFORM: - VectorSet(tcmat + 0, t->tcmod_parms[0], t->tcmod_parms[1], 0); - VectorSet(tcmat + 3, t->tcmod_parms[2], t->tcmod_parms[3], 0); - VectorSet(tcmat + 6, 0 , 0 , 1); - VectorSet(tcmat + 9, t->tcmod_parms[4], t->tcmod_parms[5], 0); - Matrix4x4_FromArray12FloatGL(&t->currenttexmatrix, tcmat); - break; - case Q3TCMOD_TURBULENT: - // this is handled in the RSurf_PrepareVertices function - t->currenttexmatrix = identitymatrix; - break; + { + matrix4x4_t temp = t->currenttexmatrix; + Matrix4x4_Concat(&t->currenttexmatrix, &matrix, &temp); + } } t->colormapping = VectorLength2(ent->colormap_pantscolor) + VectorLength2(ent->colormap_shirtcolor) >= (1.0f / 1048576.0f); @@ -3827,10 +3839,13 @@ void RSurf_PrepareVerticesForBatch(qboolean generatenormals, qboolean generateta } // the only tcmod that needs software vertex processing is turbulent, so // check for it here and apply the changes if needed - if (rsurface.texture->tcmod == Q3TCMOD_TURBULENT) + // 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) { - amplitude = rsurface.texture->tcmod_parms[1]; - animpos = rsurface.texture->tcmod_parms[2] + r_refdef.time * rsurface.texture->tcmod_parms[3]; + amplitude = rsurface.texture->tcmod_parms[0][1]; + animpos = rsurface.texture->tcmod_parms[0][2] + r_refdef.time * rsurface.texture->tcmod_parms[0][3]; for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) { const msurface_t *surface = texturesurfacelist[texturesurfaceindex]; diff --git a/model_shared.c b/model_shared.c index e573c12b..05432325 100644 --- a/model_shared.c +++ b/model_shared.c @@ -1152,7 +1152,6 @@ void Mod_LoadQ3Shaders(void) layer->rgbgen = Q3RGBGEN_IDENTITY; layer->alphagen = Q3ALPHAGEN_IDENTITY; layer->tcgen = Q3TCGEN_TEXTURE; - layer->tcmod = Q3TCMOD_NONE; layer->blendfunc[0] = GL_ONE; layer->blendfunc[1] = GL_ZERO; } @@ -1303,7 +1302,7 @@ void Mod_LoadQ3Shaders(void) } else if (numparameters >= 2 && !strcasecmp(parameter[0], "tcmod")) { - int i; + int i, tcmodindex; // observed values: // tcmod rotate # // tcmod scale # # @@ -1314,22 +1313,30 @@ void Mod_LoadQ3Shaders(void) // tcmod turb # # # # // tcmod turb sin # # # # (this is bogus) // no other values have been observed in real shaders - for (i = 0;i < numparameters - 2 && i < Q3TCMOD_MAXPARMS;i++) - layer->tcmod_parms[i] = atof(parameter[i+2]); - if (!strcasecmp(parameter[1], "entitytranslate")) layer->tcmod = Q3TCMOD_ENTITYTRANSLATE; - else if (!strcasecmp(parameter[1], "rotate")) layer->tcmod = Q3TCMOD_ROTATE; - else if (!strcasecmp(parameter[1], "scale")) layer->tcmod = Q3TCMOD_SCALE; - else if (!strcasecmp(parameter[1], "scroll")) layer->tcmod = Q3TCMOD_SCROLL; - else if (!strcasecmp(parameter[1], "stretch")) + for (tcmodindex = 0;tcmodindex < Q3MAXTCMODS;tcmodindex++) + if (!layer->tcmod[tcmodindex]) + break; + if (tcmodindex < Q3MAXTCMODS) { - layer->tcmod = Q3TCMOD_STRETCH; - for (i = 0;i < numparameters - 3 && i < Q3TCMOD_MAXPARMS;i++) - layer->tcmod_parms[i] = atof(parameter[i+3]); - layer->tcmod_wavefunc = Mod_LoadQ3Shaders_EnumerateWaveFunc(parameter[2]); + 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; + else if (!strcasecmp(parameter[1], "stretch")) + { + layer->tcmod[tcmodindex] = Q3TCMOD_STRETCH; + for (i = 0;i < numparameters - 3 && i < Q3TCMOD_MAXPARMS;i++) + layer->tcmod_parms[tcmodindex][i] = atof(parameter[i+3]); + layer->tcmod_wavefunc[tcmodindex] = Mod_LoadQ3Shaders_EnumerateWaveFunc(parameter[2]); + } + else if (!strcasecmp(parameter[1], "transform")) layer->tcmod[tcmodindex] = Q3TCMOD_TRANSFORM; + else if (!strcasecmp(parameter[1], "turb")) layer->tcmod[tcmodindex] = Q3TCMOD_TURBULENT; + else Con_DPrintf("%s parsing warning: unknown tcmod mode %s\n", search->filenames[fileindex], parameter[1]); } - else if (!strcasecmp(parameter[1], "transform")) layer->tcmod = Q3TCMOD_TRANSFORM; - else if (!strcasecmp(parameter[1], "turb")) layer->tcmod = Q3TCMOD_TURBULENT; - else Con_DPrintf("%s parsing warning: unknown tcmod mode %s\n", search->filenames[fileindex], parameter[1]); + else + Con_DPrintf("%s parsing warning: too many tcmods on one layer\n", search->filenames[fileindex]); } // break out a level if it was } if (!strcasecmp(com_token, "}")) @@ -1593,12 +1600,12 @@ nothing GL_ZERO GL_ONE texture->rgbgen = shader->primarylayer->rgbgen; texture->alphagen = shader->primarylayer->alphagen; texture->tcgen = shader->primarylayer->tcgen; - texture->tcmod = shader->primarylayer->tcmod; + memcpy(texture->tcmod , shader->primarylayer->tcmod , sizeof(texture->tcmod)); memcpy(texture->rgbgen_parms , shader->primarylayer->rgbgen_parms , sizeof(texture->rgbgen_parms)); memcpy(texture->alphagen_parms, shader->primarylayer->alphagen_parms, sizeof(texture->alphagen_parms)); memcpy(texture->tcgen_parms , shader->primarylayer->tcgen_parms , sizeof(texture->tcgen_parms)); memcpy(texture->tcmod_parms , shader->primarylayer->tcmod_parms , sizeof(texture->tcmod_parms)); - texture->tcmod_wavefunc = shader->primarylayer->tcmod_wavefunc; + memcpy(texture->tcmod_wavefunc, shader->primarylayer->tcmod_wavefunc, sizeof(texture->tcmod_wavefunc)); // load the textures texture->numskinframes = shader->primarylayer->numframes; texture->skinframerate = shader->primarylayer->framerate; diff --git a/model_shared.h b/model_shared.h index ba863c3e..5e1e54ce 100644 --- a/model_shared.h +++ b/model_shared.h @@ -189,6 +189,7 @@ shadowmesh_t; #define Q3ALPHAGEN_MAXPARMS 1 #define Q3TCGEN_MAXPARMS 6 #define Q3TCMOD_MAXPARMS 6 +#define Q3MAXTCMODS 4 typedef enum q3wavefunc_e { @@ -270,12 +271,12 @@ typedef struct q3shaderinfo_layer_s q3rgbgen_t rgbgen; q3alphagen_t alphagen; q3tcgen_t tcgen; - q3tcmod_t tcmod; + q3tcmod_t tcmod[Q3MAXTCMODS]; float rgbgen_parms[Q3RGBGEN_MAXPARMS]; float alphagen_parms[Q3ALPHAGEN_MAXPARMS]; float tcgen_parms[Q3TCGEN_MAXPARMS]; - float tcmod_parms[Q3TCMOD_MAXPARMS]; - q3wavefunc_t tcmod_wavefunc; + float tcmod_parms[Q3MAXTCMODS][Q3TCMOD_MAXPARMS]; + q3wavefunc_t tcmod_wavefunc[Q3MAXTCMODS]; } q3shaderinfo_layer_t; @@ -372,12 +373,12 @@ typedef struct texture_s q3rgbgen_t rgbgen; q3alphagen_t alphagen; q3tcgen_t tcgen; - q3tcmod_t tcmod; + q3tcmod_t tcmod[Q3MAXTCMODS]; float rgbgen_parms[Q3RGBGEN_MAXPARMS]; float alphagen_parms[Q3ALPHAGEN_MAXPARMS]; float tcgen_parms[Q3TCGEN_MAXPARMS]; - float tcmod_parms[Q3TCMOD_MAXPARMS]; - q3wavefunc_t tcmod_wavefunc; + float tcmod_parms[Q3MAXTCMODS][Q3TCMOD_MAXPARMS]; + q3wavefunc_t tcmod_wavefunc[Q3MAXTCMODS]; qboolean colormapping; rtexture_t *basetexture; -- 2.39.2