A frustum represents a pyramid, capped at the near and far end which is used to represent either a visible area or a projection area. Can be used for a number of applications.
Inheritance: Axiom.Core.MovableObject, IRenderable
Exemple #1
0
		public override void CreateScene()
		{
			scene.AmbientLight = new ColorEx( .4f, .4f, .4f );

			Light light = scene.CreateLight( "MainLight" );
			light.Position = new Vector3( 50, 80, 0 );

			Entity head = scene.CreateEntity( "OgreHead", "ogrehead.mesh" );
			entityList.Add( head );
			scene.RootSceneNode.CreateChildSceneNode().AttachObject( head );

			Entity box = scene.CreateEntity( "Box1", "cube.mesh" );
			entityList.Add( box );
			scene.RootSceneNode.CreateChildSceneNode( new Vector3( -100, 0, 0 ), Quaternion.Identity ).AttachObject( box );

			box = scene.CreateEntity( "Box2", "cube.mesh" );
			entityList.Add( box );
			scene.RootSceneNode.CreateChildSceneNode( new Vector3( 100, 0, -300 ), Quaternion.Identity ).AttachObject( box );

			box = scene.CreateEntity( "Box3", "cube.mesh" );
			entityList.Add( box );
			scene.RootSceneNode.CreateChildSceneNode( new Vector3( -200, 100, -200 ), Quaternion.Identity ).AttachObject( box );

			frustum = new Frustum( "PlayFrustum" );
			frustum.Near = 10;
			frustum.Far = 300;

			// create a node for the frustum and attach it
			frustumNode = scene.RootSceneNode.CreateChildSceneNode( new Vector3( 0, 0, 200 ), Quaternion.Identity );

			// set the camera in a convenient position
			camera.Position = new Vector3( 0, 759, 680 );
			camera.LookAt( Vector3.Zero );

			frustumNode.AttachObject( frustum );
			frustumNode.AttachObject( camera2 );
		}
        public override void SetTextureCoordCalculation( int stage, TexCoordCalcMethod method, Frustum frustum )
        {
            // save this for texture matrix calcs later
            _texStageDesc[ stage ].autoTexCoordType = method;
            _texStageDesc[ stage ].frustum = frustum;

            SetTextureStageState( stage, TextureStage.TexCoordIndex,
                                  D3DHelper.ConvertEnum( method, _deviceManager.ActiveDevice.D3D9DeviceCaps ) |
                                  _texStageDesc[ stage ].coordIndex );
        }
		/// <summary>
		/// Sets a method for automatically calculating texture coordinates for a stage.
		/// </summary>
		/// <param name="unit">Texture stage to modify.</param>
		/// <param name="method">Calculation method to use</param>
		/// <param name="frustum">Frustum, only used for projective effects</param>
		public override void SetTextureCoordCalculation(int stage, TexCoordCalcMethod method, Frustum frustum)
		{
			texStageDesc[stage].autoTexCoordType = method;
			texStageDesc[stage].frustum = frustum;
			//texStageDesc[stage].Enabled = true;
			//if (frustum != null) MessageBox.Show(texStageDesc[stage].Enabled.ToString());
		}
 /// <summary>
 ///		Sets a method for automatically calculating texture coordinates for a stage.
 /// </summary>
 /// <param name="stage">Texture stage to modify.</param>
 /// <param name="method">Calculation method to use</param>
 /// <param name="frustum">Frustum, only used for projective effects</param>
 public abstract void SetTextureCoordCalculation(int stage, TexCoordCalcMethod method, Frustum frustum);
Exemple #5
0
		public override void SetTextureCoordCalculation( int stage, TexCoordCalcMethod method, Frustum frustum )
		{
			if ( stage > _fixedFunctionTextureUnits )
			{
				// Can't do this
				return;
			}
			float[] m = new float[ 16 ];
			Matrix4 projectionBias = Matrix4.Identity;

			// Default to no extra auto texture matrix
			_useAutoTextureMatrix = false;

			if ( !ActivateGLTextureUnit( stage ) )
				return;

			switch ( method )
			{
				case TexCoordCalcMethod.None:
					break;
				case TexCoordCalcMethod.EnvironmentMap:
					_useAutoTextureMatrix = true;
					_autoTextureMatrix = new float[ 16 ];
					_autoTextureMatrix[ 0 ] = _autoTextureMatrix[ 10 ] = _autoTextureMatrix[ 15 ] = 1.0f;
					_autoTextureMatrix[ 5 ] = -1.0f;
					break;
				case TexCoordCalcMethod.EnvironmentMapPlanar:
					// TODO not implemented
					break;
				case TexCoordCalcMethod.EnvironmentMapReflection:
					// We need an extra texture matrix here
					// This sets the texture matrix to be the inverse of the view matrix
					_useAutoTextureMatrix = true;
					MakeGLMatrix( ref m, _ViewMatrix );
					if ( _autoTextureMatrix == null )
						_autoTextureMatrix = new float[ 16 ];
					// 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 ] = m[ 0 ];
					_autoTextureMatrix[ 1 ] = m[ 4 ];
					_autoTextureMatrix[ 2 ] = -m[ 8 ];
					_autoTextureMatrix[ 4 ] = m[ 1 ];
					_autoTextureMatrix[ 5 ] = m[ 5 ];
					_autoTextureMatrix[ 6 ] = -m[ 9 ];
					_autoTextureMatrix[ 8 ] = m[ 2 ];
					_autoTextureMatrix[ 9 ] = m[ 6 ];
					_autoTextureMatrix[ 10 ] = -m[ 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:
					break;
				case TexCoordCalcMethod.ProjectiveTexture:
					_useAutoTextureMatrix = true;
					if ( _autoTextureMatrix == null )
						_autoTextureMatrix = new float[ 16 ];

					// Set scale and translation matrix for projective textures
					projectionBias = Matrix4.ClipSpace2DToImageSpace;

					projectionBias = projectionBias * frustum.ProjectionMatrix;
					projectionBias = projectionBias * frustum.ViewMatrix;
					projectionBias = projectionBias * _worldMatrix;

					MakeGLMatrix( ref _autoTextureMatrix, projectionBias );
					break;
				default:
					break;
			}


			ActivateGLTextureUnit( 0 );
		}
		/// <summary>
		///    Enables or disables projective texturing on this texture unit.
		/// </summary>
		/// <remarks>
		///	   <p>
		///	   Projective texturing allows you to generate texture coordinates 
		///	   based on a Frustum, which gives the impression that a texture is
		///	   being projected onto the surface. Note that once you have called
		///	   this method, the texture unit continues to monitor the Frustum you 
		///	   passed in and the projection will change if you can alter it. It also
		///	   means that the Frustum object you pass remains in existence for as long
		///	   as this TextureUnitState does.
		///	   </p>
		///    <p>
		///	   This effect cannot be combined with other texture generation effects, 
		///	   such as environment mapping. It also has no effect on passes which 
		///	   have a vertex program enabled - projective texturing has to be done
		///	   in the vertex program instead.
		///    </p>
		/// </remarks>
		/// <param name="enable">
		///    Whether to enable / disable
		/// </param>
		/// <param name="projectionSettings">
		///    The Frustum which will be used to derive the projection parameters.
		/// </param>
		public void SetProjectiveTexturing( bool enable, Frustum projectionSettings )
		{
			if ( enable )
			{
				var effect = new TextureEffect();
				effect.type = TextureEffectType.ProjectiveTexture;
				effect.frustum = projectionSettings;
				AddEffect( effect );
			}
			else
			{
				RemoveEffect( TextureEffectType.ProjectiveTexture );
			}
		}
Exemple #7
0
		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);
		}
		public virtual void SetTextureProjector( Frustum frust, int index )
		{
			if ( index < Config.MaxSimultaneousLights )
			{
				this.currentTextureProjector[ index ] = frust;
				this.textureViewProjMatrixDirty[ index ] = true;
				this.textureWorldViewProjMatrixDirty[ index ] = true;
				this.shadowCamDepthRangesDirty[ index ] = true;
			}
		}
		public virtual Matrix4 GetSpotlightViewProjMatrix( int index )
		{
			if ( index < Config.MaxSimultaneousLights )
			{
				Light l = GetLight( index );

				if ( l != this.blankLight && l.Type == LightType.Spotlight && this.spotlightViewProjMatrixDirty[ index ] )
				{
					var frust = new Frustum();
					var dummyNode = new SceneNode( null );
					dummyNode.AttachObject( frust );

					frust.ProjectionType = Projection.Perspective;
					frust.FieldOfView = l.SpotlightOuterAngle;
					frust.AspectRatio = 1.0f;
					// set near clip the same as main camera, since they are likely
					// to both reflect the nature of the scene
					frust.Near = this.currentCamera.Near;
					// Calculate position, which same as spotlight position, in camera-relative coords if required
					dummyNode.Position = l.GetDerivedPosition( true );
					// Calculate direction, which same as spotlight direction
					Vector3 dir = -l.DerivedDirection; // backwards since point down -z
					dir.Normalize();
					Vector3 up = Vector3.UnitY;
					// Check it's not coincident with dir
					if ( Math.Utility.Abs( up.Dot( dir ) ) >= 1.0f )
					{
						// Use camera up
						up = Vector3.UnitZ;
					}
					// cross twice to rederive, only direction is unaltered
					Vector3 left = dir.Cross( up );
					left.Normalize();
					up = dir.Cross( left );
					up.Normalize();
					// Derive quaternion from axes
					Quaternion q = Quaternion.FromAxes( left, up, dir );
					dummyNode.Orientation = q;

					// The view matrix here already includes camera-relative changes if necessary
					// since they are built into the frustum position
					this.spotlightViewProjMatrix[ index ] = this.ProjectionClipSpace2DToImageSpacePerspective*
					                                        frust.ProjectionMatrixRSDepth*
					                                        frust.ViewMatrix;

					this.spotlightViewProjMatrixDirty[ index ] = false;
				}
				return this.spotlightViewProjMatrix[ index ];
			}
			else
			{
				return Matrix4.Identity;
			}
		}
		public void SetTextureProjector( Frustum frust )
		{
			SetTextureProjector( frust, 0 );
		}
        public Camera(string name, SceneManager sceneManager)
        {
            // Record name & SceneManager
            this.name = name;
            this.sceneManager = sceneManager;

            // Init camera location & direction

            // Locate at (0,0,0)
            orientation = Quaternion.Identity;
            position = Vector3.Zero;
            derivedOrientation = Quaternion.Identity;
            derivedPosition = Vector3.Zero;

            // Reasonable defaults to camera params
            sceneDetail = SceneDetailLevel.Solid;

            // Init no tracking
            autoTrackTarget = null;
            autoTrackOffset = Vector3.Zero;

            // default these to 1 so Lod default to normal
            sceneLodFactor = this.invSceneLodFactor = 1.0f;
            lastViewport = null;
            autoAspectRatio = false;
            cullingFrustum = null;
            // default to using the rendering distance
            useRenderingDistance = true;

            fieldOfView = MathUtil.RadiansToDegrees(MathUtil.PI / 4.0f);
            nearDistance = 100.0f;
            farDistance = 100000.0f;
            aspectRatio = 1.33333333333333f;
            projectionType = Projection.Perspective;

            // Default to fixed yaw (freelook)
            this.FixedYawAxis = Vector3.UnitY;

            InvalidateFrustum();
            InvalidateView();

            viewMatrix = Matrix4.Zero;
            projectionMatrix = Matrix4.Zero;

            parentNode = null;

            // no reflection
            isReflected = false;

            isVisible = false;
        }
 /// <summary>
 /// 
 /// </summary>
 /// <param name="stage"></param>
 /// <param name="method"></param>
 public override void SetTextureCoordCalculation(int stage, TexCoordCalcMethod method, Frustum frustum)
 {
     // save this for texture matrix calcs later
     if (texStageDesc[stage].autoTexCoordType != method || texStageDesc[stage].frustum != frustum) {
         // We will need ot recalculate the texture matrix
         cache.usingTextureMatrix[stage] = false;
         texStageDesc[stage].autoTexCoordType = method;
         texStageDesc[stage].frustum = frustum;
     }
     SetTextureCoordSetInternal(stage, texStageDesc[stage].coordIndex);
 }
 /// <summary>
 ///		Sets the current texture projector for a index
 /// </summary>
 public void SetTextureProjector(Frustum frust, int index)
 {
     currentTextureProjector[index] = frust;
     textureViewProjMatrixDirty[index] = true;
 }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="stage"></param>
        /// <param name="method"></param>
        public override void SetTextureCoordCalculation(int stage, TexCoordCalcMethod method, Frustum frustum)
        {
            // Default to no extra auto texture matrix
            useAutoTextureMatrix = false;

            if(method == TexCoordCalcMethod.None &&
                lastTexCalMethods[stage] == method) {
                return;
            }

            // store for next checking next time around
            lastTexCalMethods[stage] = method;

            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};

            Gl.glActiveTextureARB(Gl.GL_TEXTURE0 + stage );

            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(glSupport.CheckMinVersion("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;

                    Gl.glGetFloatv(Gl.GL_MODELVIEW_MATRIX, 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.Zero;
                    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;
                    projectionBias = projectionBias * frustum.ViewMatrix;
                    projectionBias = projectionBias * worldMatrix;

                    MakeGLMatrix( ref projectionBias, autoTextureMatrix );
                    break;

                default:
                    break;
            }

            Gl.glActiveTextureARB(Gl.GL_TEXTURE0);
        }