OpenGL2: Fix applying tcMod turb
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.
This commit is contained in:
1 parent
5ede35d8dd
commit
93abc60a5b
6 files changed
+190
-77
No files matched your search
+87
-41
@@ -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:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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);
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
@@ -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)
|
||||
|
||||
Reference in new issue
Block a user