Axiom.SceneManagers.Bsp.BspSceneManager.RenderTextureShadowOnGeometry C# (CSharp) Method

RenderTextureShadowOnGeometry() protected method

Renders texture shadow on tagged in level geometry.
protected RenderTextureShadowOnGeometry ( ) : void
return void
		protected void RenderTextureShadowOnGeometry()
		{
			// no world transform required
			targetRenderSystem.WorldMatrix = Matrix4.Identity;

			// Set view / proj
			targetRenderSystem.ViewMatrix = cameraInProgress.ViewMatrix;
			targetRenderSystem.ProjectionMatrix = cameraInProgress.ProjectionMatrix;

			Camera shadowCam = null;
			Vector3 camPos = Vector3.Zero, camDir = Vector3.Zero;
			TextureUnitState shadowTex = shadowReceiverPass.GetTextureUnitState( 0 );

			for ( int i = 0; i < shadowTex.NumEffects; i++ )
			{
				if ( shadowTex.GetEffect( i ).type == TextureEffectType.ProjectiveTexture )
				{
					shadowCam = (Camera)shadowTex.GetEffect( i ).frustum;
					camPos = shadowCam.DerivedPosition;
					camDir = shadowCam.DerivedDirection;
					break;
				}
			}

			CullingMode prevCullMode = shadowReceiverPass.CullingMode;
			LayerBlendModeEx colorBlend = shadowTex.ColorBlendMode;
			LayerBlendSource prevSource = colorBlend.source2;
			ColorEx prevColorArg = colorBlend.colorArg2;

			// Quake uses counter-clockwise culling
			shadowReceiverPass.CullingMode = CullingMode.CounterClockwise;
			colorBlend.source2 = LayerBlendSource.Manual;
			colorBlend.colorArg2 = ColorEx.White;

			SetPass( shadowReceiverPass );

			shadowReceiverPass.CullingMode = prevCullMode;
			colorBlend.source2 = prevSource;
			colorBlend.colorArg2 = prevColorArg;

			// Empty existing cache
			renderOp.indexData.indexCount = 0;

			// lock index buffer ready to receive data
			unsafe
			{
				uint* pIdx = (uint*)renderOp.indexData.indexBuffer.Lock( BufferLocking.Discard );

				// For each material in turn, cache rendering data
				IEnumerator mapEnu = matFaceGroupMap.Keys.GetEnumerator();

				while ( mapEnu.MoveNext() )
				{
					// Get Material
					Material thisMaterial = (Material)mapEnu.Current;
					BspStaticFaceGroup[] faceGrp = matFaceGroupMap[ thisMaterial ].ToArray();

					// if one face group is a quake shader then the material is a quake shader
					if ( faceGrp[ 0 ].isQuakeShader )
						continue;

					for ( int i = 0; i < faceGrp.Length; i++ )
					{
						float dist = faceGrp[ i ].plane.GetDistance( camPos );
						float angle = faceGrp[ i ].plane.Normal.Dot( camDir );

						if ( ( ( dist < 0 && angle > 0 ) || ( dist > 0 && angle < 0 ) ) &&
							Utility.Abs( angle ) >= Utility.Cos( shadowCam.FieldOfView * 0.5f ) )
						{
							// face is in shadow's frustum

							// Cache each
							int numElems = CacheGeometry( (IntPtr)pIdx, faceGrp[ i ] );
							renderOp.indexData.indexCount += numElems;
							pIdx += numElems;
						}
					}
				}
			}

			// Unlock the buffer
			renderOp.indexData.indexBuffer.Unlock();

			// Skip if no faces to process
			if ( renderOp.indexData.indexCount == 0 )
				return;

			targetRenderSystem.Render( renderOp );
		}