Example #1
0
 private void SetTechnique(StencilMethod method)
 {
     if (method == StencilMethod.ZFail)
     {
         effect.TechniqueIndex = this.failTechniqueIndex;
     }
     else
     {
         effect.TechniqueIndex = this.passTechniqueIndex;
     }
 }
Example #2
0
        /// <summary>
        /// Calculates a the ShadowVolume for a certain lightPosition.
        /// </summary>
        /// <param name="light">The light that is used for casting the ShadowVolume.</param>
        /// <param name="world">The object to world space matrix.</param>
        /// <param name="recalcFaceNormals">Recalculates the face normals. This is just necessary if the vertices
        /// of the mesh are manipulated by the CPU like for SoftwareSkinning.</param>
        /// <returns>The ShadowVolume in form of an Mesh.</returns>
        public Mesh Calculate(Light light, Matrix4 world, bool recalcFaceNormals)
        {
            // Init variables
            int j = 0;

            // Calculate the object space light vector
            this.world = world;
            Vector4 osLight = light.Vector4 * Matrix4.Invert(world);

            // calc the method to use
            if (method == StencilMethod.Automatic)
            {
                currentMethod = CalcMethod(light, world);
            }
            else
            {
                currentMethod = method;
            }
            SetTechnique(currentMethod);

            // for all subsets of the mesh add the silohuette
            for (int iSubSet = 0; iSubSet < mesh.SubSets.Count; iSubSet++)
            {
                SubSet subset = mesh.SubSets[iSubSet];
                SubSet shadow = shadowVolume.SubSets[iSubSet];

                // get indices and positions
                PositionStream positionStream = (PositionStream)subset.VertexUnit[typeof(PositionStream)];

                // recalc face normals
                if (recalcFaceNormals)
                {
                    faceNormals[iSubSet] = subset.CalcFaceNormals();
                }

                shadow.IndexBufferStart = j;

                CalcVisibilityInfo(ref j, iSubSet, osLight);

                if (indexStream.ElementSize == 2)
                {
                    AddShadowVolume16(ref j, iSubSet, light, positionStream.Size / 2);
                }
                else
                {
                    AddShadowVolume32(ref j, iSubSet, light, positionStream.Size / 2);
                }
                shadow.PrimitiveCount = (j - shadow.IndexBufferStart) / 3;
            }

            indexStream.Upload();
            return(shadowVolume);
        }