示例#1
0
 public void Remove(IDrawableBatch batchToRemove)
 {
     mBatches.Remove(batchToRemove);
 }
示例#2
0
 internal void Add(IDrawableBatch drawableBatch)
 {
     mBatches.Add(drawableBatch);
 }
示例#3
0
        private static void DrawMixed(SpriteList spriteListUnfiltered, SortType sortType,
                                      PositionedObjectList <Text> textListUnfiltered, List <IDrawableBatch> batches,
                                      bool relativeToCamera, Camera camera, Section section)
        {
            if (section != null)
            {
                Section.GetAndStartContextAndTime("Start of Draw Mixed");
            }
            DrawMixedStart(camera);



            int spriteIndex = 0;
            int textIndex   = 0;
            int batchIndex  = 0;

            // The sort values can represent different
            // things depending on the sortType argument.
            // They can either represent pure Z values or they
            // can represent distance from the camera (squared).
            // The problem is that a larger Z means closer to the
            // camera, but a larger distance means further from the
            // camera.  Therefore, to fix this problem if these values
            // represent distance from camera, they will be multiplied by
            // negative 1.
            float nextSpriteSortValue = float.PositiveInfinity;
            float nextTextSortValue   = float.PositiveInfinity;
            float nextBatchSortValue  = float.PositiveInfinity;



            if (section != null)
            {
                Section.EndContextAndTime();
                Section.GetAndStartContextAndTime("Sort Lists");
            }

            SortAllLists(spriteListUnfiltered, sortType, textListUnfiltered, batches, relativeToCamera, camera);

            mVisibleSprites.Clear();
            mVisibleTexts.Clear();
            for (int i = 0; i < spriteListUnfiltered.Count; i++)
            {
                Sprite sprite    = spriteListUnfiltered[i];
                bool   isVisible = sprite.AbsoluteVisible &&
                                   (sprite.ColorOperation == ColorOperation.InterpolateColor || sprite.Alpha > .0001) &&
                                   camera.IsSpriteInView(sprite, relativeToCamera);

                if (isVisible)
                {
                    mVisibleSprites.Add(sprite);
                }
            }

            for (int i = 0; i < textListUnfiltered.Count; i++)
            {
                Text text = textListUnfiltered[i];
                if (text.AbsoluteVisible && text.Alpha > .0001 && camera.IsTextInView(text, relativeToCamera))
                {
                    mVisibleTexts.Add(text);
                }
            }
            int indexOfNextSpriteToReposition = 0;


            GetNextZValuesByCategory(mVisibleSprites, sortType, mVisibleTexts, batches, camera, ref spriteIndex, ref textIndex, ref nextSpriteSortValue, ref nextTextSortValue, ref nextBatchSortValue);

            int numberToDraw = 0;
            // This is used as a temporary variable for Z or distance from camera
            float   sortingValue          = 0;
            Section performDrawingSection = null;

            if (section != null)
            {
                Section.EndContextAndTime();
                performDrawingSection = Section.GetAndStartContextAndTime("Perform Drawing");
            }

            while (spriteIndex < mVisibleSprites.Count || textIndex < mVisibleTexts.Count ||
                   (batches != null && batchIndex < batches.Count))
            {
                #region only 1 array remains to be drawn so finish it off completely

                #region Draw Texts
                if (spriteIndex >= mVisibleSprites.Count && (batches == null || batchIndex >= batches.Count) &&
                    textIndex < mVisibleTexts.Count)
                {
                    if (section != null)
                    {
                        if (Section.Context != performDrawingSection)
                        {
                            Section.EndContextAndTime();
                        }
                        Section.GetAndStartMergedContextAndTime("Draw Texts");
                    }

                    if (sortType == SortType.DistanceAlongForwardVector)
                    {
                        int temporaryCount = mVisibleTexts.Count;
                        for (int i = textIndex; i < temporaryCount; i++)
                        {
                            mVisibleTexts[i].Position = mVisibleTexts[i].mOldPosition;
                        }
                    }
                    // TEXTS: draw all texts from textIndex to numberOfVisibleTexts - textIndex
                    DrawTexts(mVisibleTexts, textIndex, mVisibleTexts.Count - textIndex, camera, section);
                    break;
                }
                #endregion

                #region Draw Sprites
                else if (textIndex >= mVisibleTexts.Count && (batches == null || batchIndex >= batches.Count) &&
                         spriteIndex < mVisibleSprites.Count)
                {
                    if (section != null)
                    {
                        if (Section.Context != performDrawingSection)
                        {
                            Section.EndContextAndTime();
                        }
                        Section.GetAndStartMergedContextAndTime("Draw Sprites");
                    }

                    numberToDraw = mVisibleSprites.Count - spriteIndex;
                    if (sortType == SortType.DistanceAlongForwardVector)
                    {
                        int temporaryCount = mVisibleSprites.Count;
                        for (int i = indexOfNextSpriteToReposition; i < temporaryCount; i++)
                        {
                            mVisibleSprites[i].Position = mVisibleSprites[i].mOldPosition;
                            indexOfNextSpriteToReposition++;
                        }
                    }


                    PrepareSprites(
                        mSpriteVertices, mSpriteRenderBreaks,
                        mVisibleSprites, spriteIndex, numberToDraw
                        );

                    DrawSprites(
                        mSpriteVertices, mSpriteRenderBreaks,
                        mVisibleSprites, spriteIndex,
                        numberToDraw, camera);

                    break;
                }

                #endregion

                #region Draw DrawableBatches
                else if (spriteIndex >= mVisibleSprites.Count && textIndex >= mVisibleTexts.Count &&
                         batches != null && batchIndex < batches.Count)
                {
                    if (section != null)
                    {
                        if (Section.Context != performDrawingSection)
                        {
                            Section.EndContextAndTime();
                        }
                        Section.GetAndStartMergedContextAndTime("Draw IDrawableBatches");
                    }
                    // DRAWABLE BATCHES:  Only DrawableBatches remain so draw them all.
                    while (batchIndex < batches.Count)
                    {
                        IDrawableBatch batchAtIndex = batches[batchIndex];
                        if (batchAtIndex.UpdateEveryFrame)
                        {
                            batchAtIndex.Update();
                        }

                        if (Renderer.RecordRenderBreaks)
                        {
                            // Even though we aren't using a RenderBreak here, we should record a render break
                            // for this batch as it does cause rendering to be interrupted:
                            RenderBreak renderBreak = new RenderBreak();
#if DEBUG
                            renderBreak.ObjectCausingBreak = batchAtIndex;
#endif
                            renderBreak.LayerName = CurrentLayerName;
                            LastFrameRenderBreakList.Add(renderBreak);
                        }

                        batchAtIndex.Draw(camera);

                        batchIndex++;
                    }

                    FixRenderStatesAfterBatchDraw();
                    break;
                }
                #endregion

                #endregion

                #region more than 1 list remains so find which group of objects to render

                #region Sprites

                else if (nextSpriteSortValue <= nextTextSortValue && nextSpriteSortValue <= nextBatchSortValue)
                {
                    if (section != null)
                    {
                        if (Section.Context != performDrawingSection)
                        {
                            Section.EndContextAndTime();
                        }
                        Section.GetAndStartMergedContextAndTime("Draw Sprites");
                    }
                    // The next furthest object is a Sprite.  Find how many to draw.

                    #region Count how many Sprites to draw and store it in numberToDraw
                    numberToDraw = 0;

                    if (sortType == SortType.Z || sortType == SortType.DistanceAlongForwardVector)
                    {
                        sortingValue = mVisibleSprites[spriteIndex + numberToDraw].Position.Z;
                    }
                    else
                    {
                        sortingValue = -(camera.Position - mVisibleSprites[spriteIndex + numberToDraw].Position).LengthSquared();
                    }

                    while (sortingValue <= nextTextSortValue &&
                           sortingValue <= nextBatchSortValue)
                    {
                        numberToDraw++;
                        if (spriteIndex + numberToDraw == mVisibleSprites.Count)
                        {
                            break;
                        }

                        if (sortType == SortType.Z || sortType == SortType.DistanceAlongForwardVector)
                        {
                            sortingValue = mVisibleSprites[spriteIndex + numberToDraw].Position.Z;
                        }
                        else
                        {
                            sortingValue = -(camera.Position - mVisibleSprites[spriteIndex + numberToDraw].Position).LengthSquared();
                        }
                    }
                    #endregion

                    if (sortType == SortType.DistanceAlongForwardVector)
                    {
                        for (int i = indexOfNextSpriteToReposition; i < numberToDraw + spriteIndex; i++)
                        {
                            mVisibleSprites[i].Position = mVisibleSprites[i].mOldPosition;
                            indexOfNextSpriteToReposition++;
                        }
                    }

                    PrepareSprites(
                        mSpriteVertices, mSpriteRenderBreaks,
                        mVisibleSprites, spriteIndex,
                        numberToDraw);

                    DrawSprites(
                        mSpriteVertices, mSpriteRenderBreaks,
                        mVisibleSprites, spriteIndex,
                        numberToDraw, camera);

                    // numberToDraw represents a range so increase spriteIndex by that amount.
                    spriteIndex += numberToDraw;

                    if (spriteIndex >= mVisibleSprites.Count)
                    {
                        nextSpriteSortValue = float.PositiveInfinity;
                    }
                    else
                    {
                        if (sortType == SortType.Z || sortType == SortType.DistanceAlongForwardVector || sortType == SortType.ZSecondaryParentY)
                        {
                            nextSpriteSortValue = mVisibleSprites[spriteIndex].Position.Z;
                        }
                        else
                        {
                            nextSpriteSortValue = -(camera.Position - mVisibleSprites[spriteIndex].Position).LengthSquared();
                        }
                    }
                }

                #endregion

                #region Texts


                else if (nextTextSortValue <= nextSpriteSortValue && nextTextSortValue <= nextBatchSortValue)// draw texts
                {
                    if (section != null)
                    {
                        if (Section.Context != performDrawingSection)
                        {
                            Section.EndContextAndTime();
                        }
                        Section.GetAndStartMergedContextAndTime("Draw Texts");
                    }
                    numberToDraw = 0;

                    if (sortType == SortType.Z || sortType == SortType.DistanceAlongForwardVector)
                    {
                        sortingValue = mVisibleTexts[textIndex + numberToDraw].Position.Z;
                    }
                    else
                    {
                        sortingValue = -(camera.Position - mVisibleTexts[textIndex + numberToDraw].Position).LengthSquared();
                    }


                    while (sortingValue <= nextSpriteSortValue &&
                           sortingValue <= nextBatchSortValue)
                    {
                        numberToDraw++;
                        if (textIndex + numberToDraw == mVisibleTexts.Count)
                        {
                            break;
                        }

                        if (sortType == SortType.Z || sortType == SortType.DistanceAlongForwardVector)
                        {
                            sortingValue = mVisibleTexts[textIndex + numberToDraw].Position.Z;
                        }
                        else
                        {
                            sortingValue = -(camera.Position - mVisibleTexts[textIndex + numberToDraw].Position).LengthSquared();
                        }
                    }

                    if (sortType == SortType.DistanceAlongForwardVector)
                    {
                        for (int i = textIndex; i < textIndex + numberToDraw; i++)
                        {
                            mVisibleTexts[i].Position = mVisibleTexts[i].mOldPosition;
                        }
                    }

                    DrawTexts(mVisibleTexts, textIndex, numberToDraw, camera, section);

                    textIndex += numberToDraw;

                    if (textIndex == mVisibleTexts.Count)
                    {
                        nextTextSortValue = float.PositiveInfinity;
                    }
                    else
                    {
                        if (sortType == SortType.Z || sortType == SortType.DistanceAlongForwardVector || sortType == SortType.ZSecondaryParentY)
                        {
                            nextTextSortValue = mVisibleTexts[textIndex].Position.Z;
                        }
                        else
                        {
                            nextTextSortValue = -(camera.Position - mVisibleTexts[textIndex].Position).LengthSquared();
                        }
                    }
                }

                #endregion

                #region Batches


                else if (nextBatchSortValue <= nextSpriteSortValue && nextBatchSortValue <= nextTextSortValue)
                {
                    if (section != null)
                    {
                        if (Section.Context != performDrawingSection)
                        {
                            Section.EndContextAndTime();
                        }
                        Section.GetAndStartMergedContextAndTime("Draw IDrawableBatches");
                    }
                    while (nextBatchSortValue <= nextSpriteSortValue && nextBatchSortValue <= nextTextSortValue && batchIndex < batches.Count)
                    {
                        IDrawableBatch batchAtIndex = batches[batchIndex];

                        if (batchAtIndex.UpdateEveryFrame)
                        {
                            batchAtIndex.Update();
                        }

                        if (Renderer.RecordRenderBreaks)
                        {
                            // Even though we aren't using a RenderBreak here, we should record a render break
                            // for this batch as it does cause rendering to be interrupted:
                            RenderBreak renderBreak = new RenderBreak();
#if DEBUG
                            renderBreak.ObjectCausingBreak = batchAtIndex;
#endif
                            renderBreak.LayerName = CurrentLayerName;
                            LastFrameRenderBreakList.Add(renderBreak);
                        }

                        batchAtIndex.Draw(camera);

                        batchIndex++;

                        if (batchIndex == batches.Count)
                        {
                            nextBatchSortValue = float.PositiveInfinity;
                        }
                        else
                        {
                            batchAtIndex = batches[batchIndex];

                            if (sortType == SortType.Z || sortType == SortType.ZSecondaryParentY)
                            {
                                nextBatchSortValue = batchAtIndex.Z;
                            }
                            else if (sortType == SortType.DistanceAlongForwardVector)
                            {
                                Vector3 vectorDifference = new Vector3(
                                    batchAtIndex.X - camera.X,
                                    batchAtIndex.Y - camera.Y,
                                    batchAtIndex.Z - camera.Z);

                                float   firstDistance;
                                Vector3 forwardVector = camera.RotationMatrix.Forward;

                                Vector3.Dot(ref vectorDifference, ref forwardVector, out firstDistance);

                                nextBatchSortValue = -firstDistance;
                            }
                            else
                            {
                                nextBatchSortValue = -(batchAtIndex.Z * batchAtIndex.Z);
                            }
                        }
                    }

                    FixRenderStatesAfterBatchDraw();
                }


                #endregion

                #endregion
            }

            if (section != null)
            {
                // Hop up a level
                if (Section.Context != performDrawingSection)
                {
                    Section.EndContextAndTime();
                }
                Section.EndContextAndTime();
                Section.GetAndStartContextAndTime("End of Draw Mixed");
            }

            // return the position of any objects not drawn
            if (sortType == SortType.DistanceAlongForwardVector)
            {
                for (int i = indexOfNextSpriteToReposition; i < mVisibleSprites.Count; i++)
                {
                    mVisibleSprites[i].Position = mVisibleSprites[i].mOldPosition;
                }
            }

            Renderer.Texture         = null;
            Renderer.TextureOnDevice = null;

            if (section != null)
            {
                Section.EndContextAndTime();
            }
        }