public override void SetTextureCoordCalculation( int stage, TexCoordCalcMethod method, Frustum frustum )
{
if (stage >= _fixedFunctionTextureUnits)
{
// Can't do this
return;
}
// Default to no extra auto texture matrix
useAutoTextureMatrix = false;
float[] eyePlaneS = { 1.0f, 0.0f, 0.0f, 0.0f };
float[] eyePlaneT = { 0.0f, 1.0f, 0.0f, 0.0f };
float[] eyePlaneR = { 0.0f, 0.0f, 1.0f, 0.0f };
float[] eyePlaneQ = { 0.0f, 0.0f, 0.0f, 1.0f };
if (!ActivateGLTextureUnit(stage))
return;
switch ( method )
{
case TexCoordCalcMethod.None:
Gl.glDisable( Gl.GL_TEXTURE_GEN_S );
Gl.glDisable( Gl.GL_TEXTURE_GEN_T );
Gl.glDisable( Gl.GL_TEXTURE_GEN_R );
Gl.glDisable( Gl.GL_TEXTURE_GEN_Q );
break;
case TexCoordCalcMethod.EnvironmentMap:
Gl.glTexGeni( Gl.GL_S, Gl.GL_TEXTURE_GEN_MODE, Gl.GL_SPHERE_MAP );
Gl.glTexGeni( Gl.GL_T, Gl.GL_TEXTURE_GEN_MODE, Gl.GL_SPHERE_MAP );
Gl.glEnable( Gl.GL_TEXTURE_GEN_S );
Gl.glEnable( Gl.GL_TEXTURE_GEN_T );
Gl.glDisable( Gl.GL_TEXTURE_GEN_R );
Gl.glDisable( Gl.GL_TEXTURE_GEN_Q );
// Need to use a texture matrix to flip the spheremap
useAutoTextureMatrix = true;
Array.Clear( autoTextureMatrix, 0, 16 );
autoTextureMatrix[ 0 ] = autoTextureMatrix[ 10 ] = autoTextureMatrix[ 15 ] = 1.0f;
autoTextureMatrix[ 5 ] = -1.0f;
break;
case TexCoordCalcMethod.EnvironmentMapPlanar:
// XXX This doesn't seem right?!
if ( GL_VERSION_1_3 )
{
Gl.glTexGeni( Gl.GL_S, Gl.GL_TEXTURE_GEN_MODE, Gl.GL_REFLECTION_MAP );
Gl.glTexGeni( Gl.GL_T, Gl.GL_TEXTURE_GEN_MODE, Gl.GL_REFLECTION_MAP );
Gl.glTexGeni( Gl.GL_R, Gl.GL_TEXTURE_GEN_MODE, Gl.GL_REFLECTION_MAP );
Gl.glEnable( Gl.GL_TEXTURE_GEN_S );
Gl.glEnable( Gl.GL_TEXTURE_GEN_T );
Gl.glEnable( Gl.GL_TEXTURE_GEN_R );
Gl.glDisable( Gl.GL_TEXTURE_GEN_Q );
}
else
{
Gl.glTexGeni( Gl.GL_S, Gl.GL_TEXTURE_GEN_MODE, Gl.GL_SPHERE_MAP );
Gl.glTexGeni( Gl.GL_T, Gl.GL_TEXTURE_GEN_MODE, Gl.GL_SPHERE_MAP );
Gl.glEnable( Gl.GL_TEXTURE_GEN_S );
Gl.glEnable( Gl.GL_TEXTURE_GEN_T );
Gl.glDisable( Gl.GL_TEXTURE_GEN_R );
Gl.glDisable( Gl.GL_TEXTURE_GEN_Q );
}
break;
case TexCoordCalcMethod.EnvironmentMapReflection:
Gl.glTexGeni( Gl.GL_S, Gl.GL_TEXTURE_GEN_MODE, Gl.GL_REFLECTION_MAP );
Gl.glTexGeni( Gl.GL_T, Gl.GL_TEXTURE_GEN_MODE, Gl.GL_REFLECTION_MAP );
Gl.glTexGeni( Gl.GL_R, Gl.GL_TEXTURE_GEN_MODE, Gl.GL_REFLECTION_MAP );
Gl.glEnable( Gl.GL_TEXTURE_GEN_S );
Gl.glEnable( Gl.GL_TEXTURE_GEN_T );
Gl.glEnable( Gl.GL_TEXTURE_GEN_R );
Gl.glDisable( Gl.GL_TEXTURE_GEN_Q );
// We need an extra texture matrix here
// This sets the texture matrix to be the inverse of the modelview matrix
useAutoTextureMatrix = true;
MakeGLMatrix(ref viewMatrix, _tempMatrix);
// Transpose 3x3 in order to invert matrix (rotation)
// Note that we need to invert the Z _before_ the rotation
// No idea why we have to invert the Z at all, but reflection is wrong without it
autoTextureMatrix[ 0 ] = _tempMatrix[ 0 ];
autoTextureMatrix[ 1 ] = _tempMatrix[ 4 ];
autoTextureMatrix[ 2 ] = -_tempMatrix[ 8 ];
autoTextureMatrix[ 4 ] = _tempMatrix[ 1 ];
autoTextureMatrix[ 5 ] = _tempMatrix[ 5 ];
autoTextureMatrix[ 6 ] = -_tempMatrix[ 9 ];
autoTextureMatrix[ 8 ] = _tempMatrix[ 2 ];
autoTextureMatrix[ 9 ] = _tempMatrix[ 6 ];
autoTextureMatrix[ 10 ] = -_tempMatrix[ 10 ];
autoTextureMatrix[ 3 ] = autoTextureMatrix[ 7 ] = autoTextureMatrix[ 11 ] = 0.0f;
autoTextureMatrix[ 12 ] = autoTextureMatrix[ 13 ] = autoTextureMatrix[ 14 ] = 0.0f;
autoTextureMatrix[ 15 ] = 1.0f;
break;
case TexCoordCalcMethod.EnvironmentMapNormal:
Gl.glTexGeni( Gl.GL_S, Gl.GL_TEXTURE_GEN_MODE, Gl.GL_NORMAL_MAP );
Gl.glTexGeni( Gl.GL_T, Gl.GL_TEXTURE_GEN_MODE, Gl.GL_NORMAL_MAP );
Gl.glTexGeni( Gl.GL_R, Gl.GL_TEXTURE_GEN_MODE, Gl.GL_NORMAL_MAP );
Gl.glEnable( Gl.GL_TEXTURE_GEN_S );
Gl.glEnable( Gl.GL_TEXTURE_GEN_T );
Gl.glEnable( Gl.GL_TEXTURE_GEN_R );
Gl.glDisable( Gl.GL_TEXTURE_GEN_Q );
break;
case TexCoordCalcMethod.ProjectiveTexture:
Gl.glTexGeni( Gl.GL_S, Gl.GL_TEXTURE_GEN_MODE, Gl.GL_EYE_LINEAR );
Gl.glTexGeni( Gl.GL_T, Gl.GL_TEXTURE_GEN_MODE, Gl.GL_EYE_LINEAR );
Gl.glTexGeni( Gl.GL_R, Gl.GL_TEXTURE_GEN_MODE, Gl.GL_EYE_LINEAR );
Gl.glTexGeni( Gl.GL_Q, Gl.GL_TEXTURE_GEN_MODE, Gl.GL_EYE_LINEAR );
Gl.glTexGenfv( Gl.GL_S, Gl.GL_EYE_PLANE, eyePlaneS );
Gl.glTexGenfv( Gl.GL_T, Gl.GL_EYE_PLANE, eyePlaneT );
Gl.glTexGenfv( Gl.GL_R, Gl.GL_EYE_PLANE, eyePlaneR );
Gl.glTexGenfv( Gl.GL_Q, Gl.GL_EYE_PLANE, eyePlaneQ );
Gl.glEnable( Gl.GL_TEXTURE_GEN_S );
Gl.glEnable( Gl.GL_TEXTURE_GEN_T );
Gl.glEnable( Gl.GL_TEXTURE_GEN_R );
Gl.glEnable( Gl.GL_TEXTURE_GEN_Q );
useAutoTextureMatrix = true;
// Set scale and translation matrix for projective textures
Matrix4 projectionBias = Matrix4.ClipSpace2DToImageSpace;
//projectionBias.m00 = 0.5f;
//projectionBias.m11 = -0.5f;
//projectionBias.m22 = 1.0f;
//projectionBias.m03 = 0.5f;
//projectionBias.m13 = 0.5f;
//projectionBias.m33 = 1.0f;
projectionBias = projectionBias * frustum.ProjectionMatrix;
if (texProjRelative)
{
Matrix4 tmp;
frustum.CalcViewMatrixRelative(texProjRelativeOrigin, out tmp);
projectionBias = projectionBias * tmp;
}
else
{
projectionBias = projectionBias*frustum.ViewMatrix;
}
projectionBias = projectionBias * worldMatrix;
MakeGLMatrix( ref projectionBias, autoTextureMatrix );
break;
default:
break;
}
ActivateGLTextureUnit(0);
}