Ejemplo n.º 1
0
        /// <summary>
        /// Renders the queue auf the QuadManager.
        /// </summary>
        /// <param name="deltaTime">The time since the last frame.</param>
        public void OnRender(float deltaTime)
        {
            // if there is nothing to draw return
            if (quadsFilled == 0)
            {
                return;
            }

            // Begin
            Device.Instance.IndexStream = indexStream;
            totalQuads     = 0;
            factoryChanges = 0;
            textureChanges = 0;

            // Create the batches
            CreateBatches();
            // Upload the VertexUnits and the IndexStream
            foreach (IQuadFactory factory in quadFactories)
            {
                factory.Upload();
            }
            indexStream.Upload(0, indexFilled);
            // Render the batches
            RenderBatches();

            // End
            batchFilled = 0;
            indexFilled = 0;
            quadsFilled = 0;
        }
Ejemplo n.º 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);
        }