Skip to content

Commit

Permalink
OpenGL2: Fix applying tcMod turb
Browse files Browse the repository at this point in the history
Shader stage tcMods for matrix and turb effects need to be applied in
order for turb to be correct and all tcMod turb need to be applied
instead of only the last one.

Quake 3's textures/liquids/slime1 had tcMod turb and then tcMod scale.
OpenGL2 applied the matrix first and then turb which had the wrong result.
  • Loading branch information
zturtleman committed Jan 18, 2024
1 parent 5ede35d commit 93abc60
Show file tree
Hide file tree
Showing 6 changed files with 190 additions and 77 deletions.
54 changes: 40 additions & 14 deletions code/renderergl2/glsl/generic_vp.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,16 @@ attribute vec4 attr_TexCoord0;
attribute vec4 attr_TexCoord1;
#endif

uniform vec4 u_DiffuseTexMatrix;
uniform vec4 u_DiffuseTexOffTurb;
#if defined(USE_TCMOD)
uniform vec4 u_DiffuseTexMatrix0;
uniform vec4 u_DiffuseTexMatrix1;
uniform vec4 u_DiffuseTexMatrix2;
uniform vec4 u_DiffuseTexMatrix3;
uniform vec4 u_DiffuseTexMatrix4;
uniform vec4 u_DiffuseTexMatrix5;
uniform vec4 u_DiffuseTexMatrix6;
uniform vec4 u_DiffuseTexMatrix7;
#endif

#if defined(USE_TCGEN) || defined(USE_RGBAGEN)
uniform vec3 u_LocalViewOrigin;
Expand Down Expand Up @@ -140,19 +148,28 @@ vec2 GenTexCoords(int TCGen, vec3 position, vec3 normal, vec3 TCGenVector0, vec3
#endif

#if defined(USE_TCMOD)
vec2 ModTexCoords(vec2 st, vec3 position, vec4 texMatrix, vec4 offTurb)
vec2 ModTexCoords(vec2 st, vec3 position, vec4 texMatrix[8])
{
float amplitude = offTurb.z;
float phase = offTurb.w * 2.0 * M_PI;
vec2 st2;
st2.x = st.x * texMatrix.x + (st.y * texMatrix.z + offTurb.x);
st2.y = st.x * texMatrix.y + (st.y * texMatrix.w + offTurb.y);

vec2 st2 = st;
vec2 offsetPos = vec2(position.x + position.z, position.y);

vec2 texOffset = sin(offsetPos * (2.0 * M_PI / 1024.0) + vec2(phase));

return st2 + texOffset * amplitude;

st2 = vec2(st2.x * texMatrix[0].x + st2.y * texMatrix[0].y + texMatrix[0].z,
st2.x * texMatrix[1].x + st2.y * texMatrix[1].y + texMatrix[1].z);
st2 += texMatrix[0].w * sin(offsetPos * (2.0 * M_PI / 1024.0) + vec2(texMatrix[1].w * 2.0 * M_PI));

st2 = vec2(st2.x * texMatrix[2].x + st2.y * texMatrix[2].y + texMatrix[2].z,
st2.x * texMatrix[3].x + st2.y * texMatrix[3].y + texMatrix[3].z);
st2 += texMatrix[2].w * sin(offsetPos * (2.0 * M_PI / 1024.0) + vec2(texMatrix[3].w * 2.0 * M_PI));

st2 = vec2(st2.x * texMatrix[4].x + st2.y * texMatrix[4].y + texMatrix[4].z,
st2.x * texMatrix[5].x + st2.y * texMatrix[5].y + texMatrix[5].z);
st2 += texMatrix[4].w * sin(offsetPos * (2.0 * M_PI / 1024.0) + vec2(texMatrix[5].w * 2.0 * M_PI));

st2 = vec2(st2.x * texMatrix[6].x + st2.y * texMatrix[6].y + texMatrix[6].z,
st2.x * texMatrix[7].x + st2.y * texMatrix[7].y + texMatrix[7].z);
st2 += texMatrix[6].w * sin(offsetPos * (2.0 * M_PI / 1024.0) + vec2(texMatrix[7].w * 2.0 * M_PI));

return st2;
}
#endif

Expand Down Expand Up @@ -236,7 +253,16 @@ void main()
#endif

#if defined(USE_TCMOD)
var_DiffuseTex = ModTexCoords(tex, position, u_DiffuseTexMatrix, u_DiffuseTexOffTurb);
vec4 diffuseTexMatrix[8];
diffuseTexMatrix[0] = u_DiffuseTexMatrix0;
diffuseTexMatrix[1] = u_DiffuseTexMatrix1;
diffuseTexMatrix[2] = u_DiffuseTexMatrix2;
diffuseTexMatrix[3] = u_DiffuseTexMatrix3;
diffuseTexMatrix[4] = u_DiffuseTexMatrix4;
diffuseTexMatrix[5] = u_DiffuseTexMatrix5;
diffuseTexMatrix[6] = u_DiffuseTexMatrix6;
diffuseTexMatrix[7] = u_DiffuseTexMatrix7;
var_DiffuseTex = ModTexCoords(tex, position, diffuseTexMatrix);
#else
var_DiffuseTex = tex;
#endif
Expand Down
48 changes: 36 additions & 12 deletions code/renderergl2/glsl/lightall_vp.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,14 @@ uniform vec3 u_LocalViewOrigin;
#endif

#if defined(USE_TCMOD)
uniform vec4 u_DiffuseTexMatrix;
uniform vec4 u_DiffuseTexOffTurb;
uniform vec4 u_DiffuseTexMatrix0;
uniform vec4 u_DiffuseTexMatrix1;
uniform vec4 u_DiffuseTexMatrix2;
uniform vec4 u_DiffuseTexMatrix3;
uniform vec4 u_DiffuseTexMatrix4;
uniform vec4 u_DiffuseTexMatrix5;
uniform vec4 u_DiffuseTexMatrix6;
uniform vec4 u_DiffuseTexMatrix7;
#endif

uniform mat4 u_ModelViewProjectionMatrix;
Expand Down Expand Up @@ -114,19 +120,28 @@ vec2 GenTexCoords(int TCGen, vec3 position, vec3 normal, vec3 TCGenVector0, vec3
#endif

#if defined(USE_TCMOD)
vec2 ModTexCoords(vec2 st, vec3 position, vec4 texMatrix, vec4 offTurb)
vec2 ModTexCoords(vec2 st, vec3 position, vec4 texMatrix[8])
{
float amplitude = offTurb.z;
float phase = offTurb.w * 2.0 * M_PI;
vec2 st2;
st2.x = st.x * texMatrix.x + (st.y * texMatrix.z + offTurb.x);
st2.y = st.x * texMatrix.y + (st.y * texMatrix.w + offTurb.y);

vec2 st2 = st;
vec2 offsetPos = vec2(position.x + position.z, position.y);

vec2 texOffset = sin(offsetPos * (2.0 * M_PI / 1024.0) + vec2(phase));
st2 = vec2(st2.x * texMatrix[0].x + st2.y * texMatrix[0].y + texMatrix[0].z,
st2.x * texMatrix[1].x + st2.y * texMatrix[1].y + texMatrix[1].z);
st2 += texMatrix[0].w * sin(offsetPos * (2.0 * M_PI / 1024.0) + vec2(texMatrix[1].w * 2.0 * M_PI));

st2 = vec2(st2.x * texMatrix[2].x + st2.y * texMatrix[2].y + texMatrix[2].z,
st2.x * texMatrix[3].x + st2.y * texMatrix[3].y + texMatrix[3].z);
st2 += texMatrix[2].w * sin(offsetPos * (2.0 * M_PI / 1024.0) + vec2(texMatrix[3].w * 2.0 * M_PI));

st2 = vec2(st2.x * texMatrix[4].x + st2.y * texMatrix[4].y + texMatrix[4].z,
st2.x * texMatrix[5].x + st2.y * texMatrix[5].y + texMatrix[5].z);
st2 += texMatrix[4].w * sin(offsetPos * (2.0 * M_PI / 1024.0) + vec2(texMatrix[5].w * 2.0 * M_PI));

st2 = vec2(st2.x * texMatrix[6].x + st2.y * texMatrix[6].y + texMatrix[6].z,
st2.x * texMatrix[7].x + st2.y * texMatrix[7].y + texMatrix[7].z);
st2 += texMatrix[6].w * sin(offsetPos * (2.0 * M_PI / 1024.0) + vec2(texMatrix[7].w * 2.0 * M_PI));

return st2 + texOffset * amplitude;
return st2;
}
#endif

Expand Down Expand Up @@ -183,7 +198,16 @@ void main()
#endif

#if defined(USE_TCMOD)
var_TexCoords.xy = ModTexCoords(texCoords, position, u_DiffuseTexMatrix, u_DiffuseTexOffTurb);
vec4 diffuseTexMatrix[8];
diffuseTexMatrix[0] = u_DiffuseTexMatrix0;
diffuseTexMatrix[1] = u_DiffuseTexMatrix1;
diffuseTexMatrix[2] = u_DiffuseTexMatrix2;
diffuseTexMatrix[3] = u_DiffuseTexMatrix3;
diffuseTexMatrix[4] = u_DiffuseTexMatrix4;
diffuseTexMatrix[5] = u_DiffuseTexMatrix5;
diffuseTexMatrix[6] = u_DiffuseTexMatrix6;
diffuseTexMatrix[7] = u_DiffuseTexMatrix7;
var_TexCoords.xy = ModTexCoords(texCoords, position, diffuseTexMatrix);
#else
var_TexCoords.xy = texCoords;
#endif
Expand Down
10 changes: 8 additions & 2 deletions code/renderergl2/tr_glsl.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,14 @@ static uniformInfo_t uniformsInfo[] =

{ "u_EnableTextures", GLSL_VEC4 },

{ "u_DiffuseTexMatrix", GLSL_VEC4 },
{ "u_DiffuseTexOffTurb", GLSL_VEC4 },
{ "u_DiffuseTexMatrix0", GLSL_VEC4 },
{ "u_DiffuseTexMatrix1", GLSL_VEC4 },
{ "u_DiffuseTexMatrix2", GLSL_VEC4 },
{ "u_DiffuseTexMatrix3", GLSL_VEC4 },
{ "u_DiffuseTexMatrix4", GLSL_VEC4 },
{ "u_DiffuseTexMatrix5", GLSL_VEC4 },
{ "u_DiffuseTexMatrix6", GLSL_VEC4 },
{ "u_DiffuseTexMatrix7", GLSL_VEC4 },

{ "u_TCGen0", GLSL_INT },
{ "u_TCGen0Vector0", GLSL_VEC3 },
Expand Down
10 changes: 8 additions & 2 deletions code/renderergl2/tr_local.h
Original file line number Diff line number Diff line change
Expand Up @@ -637,8 +637,14 @@ typedef enum

UNIFORM_ENABLETEXTURES,

UNIFORM_DIFFUSETEXMATRIX,
UNIFORM_DIFFUSETEXOFFTURB,
UNIFORM_DIFFUSETEXMATRIX0,
UNIFORM_DIFFUSETEXMATRIX1,
UNIFORM_DIFFUSETEXMATRIX2,
UNIFORM_DIFFUSETEXMATRIX3,
UNIFORM_DIFFUSETEXMATRIX4,
UNIFORM_DIFFUSETEXMATRIX5,
UNIFORM_DIFFUSETEXMATRIX6,
UNIFORM_DIFFUSETEXMATRIX7,

UNIFORM_TCGEN0,
UNIFORM_TCGEN0VECTOR0,
Expand Down
128 changes: 87 additions & 41 deletions code/renderergl2/tr_shade.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,33 +181,30 @@ extern float EvalWaveForm( const waveForm_t *wf );
extern float EvalWaveFormClamped( const waveForm_t *wf );


static void ComputeTexMods( shaderStage_t *pStage, int bundleNum, float *outMatrix, float *outOffTurb)
static void ComputeTexMods( shaderStage_t *pStage, int bundleNum, vec4_t outMatrix[8])
{
int tm;
float matrix[6], currentmatrix[6];
float matrix[6];
float tmpmatrix[6];
float currentmatrix[6];
float turb[2];
textureBundle_t *bundle = &pStage->bundle[bundleNum];

matrix[0] = 1.0f; matrix[2] = 0.0f; matrix[4] = 0.0f;
matrix[1] = 0.0f; matrix[3] = 1.0f; matrix[5] = 0.0f;
qboolean hasTurb = qfalse;

currentmatrix[0] = 1.0f; currentmatrix[2] = 0.0f; currentmatrix[4] = 0.0f;
currentmatrix[1] = 0.0f; currentmatrix[3] = 1.0f; currentmatrix[5] = 0.0f;

outMatrix[0] = 1.0f; outMatrix[2] = 0.0f;
outMatrix[1] = 0.0f; outMatrix[3] = 1.0f;

outOffTurb[0] = 0.0f; outOffTurb[1] = 0.0f; outOffTurb[2] = 0.0f; outOffTurb[3] = 0.0f;

for ( tm = 0; tm < bundle->numTexMods ; tm++ ) {
switch ( bundle->texMods[tm].type )
{

case TMOD_NONE:
tm = TR_MAX_TEXMODS; // break out of for loop
matrix[0] = 1.0f; matrix[2] = 0.0f; matrix[4] = 0.0f;
matrix[1] = 0.0f; matrix[3] = 1.0f; matrix[5] = 0.0f;
break;

case TMOD_TURBULENT:
RB_CalcTurbulentFactors(&bundle->texMods[tm].wave, &outOffTurb[2], &outOffTurb[3]);
RB_CalcTurbulentFactors(&bundle->texMods[tm].wave, &turb[0], &turb[1]);
break;

case TMOD_ENTITY_TRANSLATE:
Expand Down Expand Up @@ -246,35 +243,68 @@ static void ComputeTexMods( shaderStage_t *pStage, int bundleNum, float *outMatr

switch ( bundle->texMods[tm].type )
{
case TMOD_NONE:
case TMOD_TURBULENT:
default:
outMatrix[tm*2+0][0] = 1; outMatrix[tm*2+0][1] = 0; outMatrix[tm*2+0][2] = 0;
outMatrix[tm*2+1][0] = 0; outMatrix[tm*2+1][1] = 1; outMatrix[tm*2+1][2] = 0;

outMatrix[tm*2+0][3] = turb[0];
outMatrix[tm*2+1][3] = turb[1];

hasTurb = qtrue;
break;

case TMOD_NONE:
case TMOD_ENTITY_TRANSLATE:
case TMOD_SCROLL:
case TMOD_SCALE:
case TMOD_STRETCH:
case TMOD_TRANSFORM:
case TMOD_ROTATE:
outMatrix[0] = matrix[0] * currentmatrix[0] + matrix[2] * currentmatrix[1];
outMatrix[1] = matrix[1] * currentmatrix[0] + matrix[3] * currentmatrix[1];
default:
outMatrix[tm*2+0][0] = matrix[0]; outMatrix[tm*2+0][1] = matrix[2]; outMatrix[tm*2+0][2] = matrix[4];
outMatrix[tm*2+1][0] = matrix[1]; outMatrix[tm*2+1][1] = matrix[3]; outMatrix[tm*2+1][2] = matrix[5];

outMatrix[2] = matrix[0] * currentmatrix[2] + matrix[2] * currentmatrix[3];
outMatrix[3] = matrix[1] * currentmatrix[2] + matrix[3] * currentmatrix[3];
outMatrix[tm*2+0][3] = 0;
outMatrix[tm*2+1][3] = 0;

outOffTurb[0] = matrix[0] * currentmatrix[4] + matrix[2] * currentmatrix[5] + matrix[4];
outOffTurb[1] = matrix[1] * currentmatrix[4] + matrix[3] * currentmatrix[5] + matrix[5];
tmpmatrix[0] = matrix[0] * currentmatrix[0] + matrix[2] * currentmatrix[1];
tmpmatrix[1] = matrix[1] * currentmatrix[0] + matrix[3] * currentmatrix[1];

currentmatrix[0] = outMatrix[0];
currentmatrix[1] = outMatrix[1];
currentmatrix[2] = outMatrix[2];
currentmatrix[3] = outMatrix[3];
currentmatrix[4] = outOffTurb[0];
currentmatrix[5] = outOffTurb[1];
tmpmatrix[2] = matrix[0] * currentmatrix[2] + matrix[2] * currentmatrix[3];
tmpmatrix[3] = matrix[1] * currentmatrix[2] + matrix[3] * currentmatrix[3];

tmpmatrix[4] = matrix[0] * currentmatrix[4] + matrix[2] * currentmatrix[5] + matrix[4];
tmpmatrix[5] = matrix[1] * currentmatrix[4] + matrix[3] * currentmatrix[5] + matrix[5];

currentmatrix[0] = tmpmatrix[0];
currentmatrix[1] = tmpmatrix[1];
currentmatrix[2] = tmpmatrix[2];
currentmatrix[3] = tmpmatrix[3];
currentmatrix[4] = tmpmatrix[4];
currentmatrix[5] = tmpmatrix[5];
break;
}
}

// if turb isn't used, only one matrix is needed
if ( !hasTurb ) {
tm = 0;

outMatrix[tm*2+0][0] = currentmatrix[0]; outMatrix[tm*2+0][1] = currentmatrix[2]; outMatrix[tm*2+0][2] = currentmatrix[4];
outMatrix[tm*2+1][0] = currentmatrix[1]; outMatrix[tm*2+1][1] = currentmatrix[3]; outMatrix[tm*2+1][2] = currentmatrix[5];

outMatrix[tm*2+0][3] = 0;
outMatrix[tm*2+1][3] = 0;
tm++;
}

for ( ; tm < TR_MAX_TEXMODS ; tm++ ) {
outMatrix[tm*2+0][0] = 1; outMatrix[tm*2+0][1] = 0; outMatrix[tm*2+0][2] = 0;
outMatrix[tm*2+1][0] = 0; outMatrix[tm*2+1][1] = 1; outMatrix[tm*2+1][2] = 0;

outMatrix[tm*2+0][3] = 0;
outMatrix[tm*2+1][3] = 0;
}
}


Expand Down Expand Up @@ -665,8 +695,7 @@ static void ForwardDlight( void ) {
dlight_t *dl;
shaderProgram_t *sp;
vec4_t vector;
vec4_t texMatrix;
vec4_t texOffTurb;
vec4_t texMatrix[8];

if ( !( tess.dlightBits & ( 1 << l ) ) ) {
continue; // this surface definitely doesn't have any of this light
Expand Down Expand Up @@ -792,9 +821,15 @@ static void ForwardDlight( void ) {
if (r_dlightMode->integer >= 2)
GL_BindToTMU(tr.shadowCubemaps[l], TB_SHADOWMAP);

ComputeTexMods( pStage, TB_DIFFUSEMAP, texMatrix, texOffTurb );
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX, texMatrix);
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXOFFTURB, texOffTurb);
ComputeTexMods( pStage, TB_DIFFUSEMAP, texMatrix );
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX0, texMatrix[0]);
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX1, texMatrix[1]);
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX2, texMatrix[2]);
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX3, texMatrix[3]);
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX4, texMatrix[4]);
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX5, texMatrix[5]);
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX6, texMatrix[6]);
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX7, texMatrix[7]);

GLSL_SetUniformInt(sp, UNIFORM_TCGEN0, pStage->bundle[0].tcGen);

Expand Down Expand Up @@ -996,8 +1031,7 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
{
shaderStage_t *pStage = input->xstages[stage];
shaderProgram_t *sp;
vec4_t texMatrix;
vec4_t texOffTurb;
vec4_t texMatrix[8];

if ( !pStage )
{
Expand Down Expand Up @@ -1184,19 +1218,31 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )

if (r_lightmap->integer)
{
vec4_t v;
VectorSet4(v, 1.0f, 0.0f, 0.0f, 1.0f);
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX, v);
VectorSet4(v, 0.0f, 0.0f, 0.0f, 0.0f);
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXOFFTURB, v);
vec4_t st[2];
VectorSet4(st[0], 1.0f, 0.0f, 0.0f, 0.0f);
VectorSet4(st[1], 0.0f, 1.0f, 0.0f, 0.0f);
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX0, st[0]);
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX1, st[1]);
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX2, st[0]);
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX3, st[1]);
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX4, st[0]);
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX5, st[1]);
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX6, st[0]);
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX7, st[1]);

GLSL_SetUniformInt(sp, UNIFORM_TCGEN0, TCGEN_LIGHTMAP);
}
else
{
ComputeTexMods(pStage, TB_DIFFUSEMAP, texMatrix, texOffTurb);
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX, texMatrix);
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXOFFTURB, texOffTurb);
ComputeTexMods(pStage, TB_DIFFUSEMAP, texMatrix);
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX0, texMatrix[0]);
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX1, texMatrix[1]);
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX2, texMatrix[2]);
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX3, texMatrix[3]);
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX4, texMatrix[4]);
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX5, texMatrix[5]);
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX6, texMatrix[6]);
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX7, texMatrix[7]);

GLSL_SetUniformInt(sp, UNIFORM_TCGEN0, pStage->bundle[0].tcGen);
if (pStage->bundle[0].tcGen == TCGEN_VECTOR)
Expand Down
Loading

0 comments on commit 93abc60

Please sign in to comment.