public void Draw(FlatRedBall.Camera camera) { ////////////////////////Early Out/////////////////////////////// if (DisableDrawing) { return; } //////////////////////End Early Out///////////////////////////// // This is the first call of the frame, so reset this value: SystemManagers.Default.Renderer.ClearPerformanceRecordingVariables(); if (FlatRedBall.Graphics.Renderer.CurrentLayer == null) { mManagers.TextManager.RenderTextTextures(); mManagers.Draw(mManagers.Renderer.MainLayer); } else if (mFrbToGumLayers.ContainsKey(FlatRedBall.Graphics.Renderer.CurrentLayer)) { mManagers.Draw(mFrbToGumLayers[FlatRedBall.Graphics.Renderer.CurrentLayer]); } var renderBreaks = FlatRedBall.Graphics.Renderer.LastFrameRenderBreakList; if (renderBreaks != null) { #if DEBUG // This object handles its own render breaks if (renderBreaks.Count != 0) { var last = renderBreaks.Last(); if (last.ObjectCausingBreak == this) { renderBreaks.RemoveAt(renderBreaks.Count - 1); } } #endif foreach (var item in mManagers.Renderer.SpriteRenderer.LastFrameDrawStates) { foreach (var changeRecord in item.ChangeRecord) { var renderBreak = new RenderBreak(0, changeRecord.Texture, ColorOperation.Texture, BlendOperation.Regular, TextureAddressMode.Clamp); #if DEBUG renderBreak.ObjectCausingBreak = changeRecord.ObjectRequestingChange; #endif renderBreaks.Add(renderBreak); } } } mManagers.Renderer.ForceEnd(); }
public static RenderBreakSave FromRenderBreak(RenderBreak renderBreak) { RenderBreakSave toReturn = new RenderBreakSave(); if (renderBreak.Texture != null) { toReturn.Texture = renderBreak.Texture.Name; } toReturn.LayerName = renderBreak.LayerName; toReturn.ColorOperation = renderBreak.ColorOperation; toReturn.BlendOperation = renderBreak.BlendOperation; toReturn.TextureFilter = renderBreak.TextureFilter; toReturn.TextureAddressMode = renderBreak.TextureAddressMode; #if DEBUG toReturn.Details = renderBreak.Details; #endif return toReturn; }
public static RenderBreakSave FromRenderBreak(RenderBreak renderBreak) { RenderBreakSave toReturn = new RenderBreakSave(); if (renderBreak.Texture != null) { toReturn.Texture = renderBreak.Texture.Name; } toReturn.LayerName = renderBreak.LayerName; toReturn.ColorOperation = renderBreak.ColorOperation; toReturn.BlendOperation = renderBreak.BlendOperation; toReturn.TextureFilter = renderBreak.TextureFilter; toReturn.TextureAddressMode = renderBreak.TextureAddressMode; #if DEBUG toReturn.Details = renderBreak.Details; #endif return(toReturn); }
public static RenderBreakViewModel FromRenderBreak(RenderBreak renderBreak) { RenderBreakViewModel toReturn = new RenderBreakViewModel(); toReturn.LayerName = renderBreak.LayerName; if (renderBreak.Texture != null) { toReturn.Texture = renderBreak.Texture.Name; } toReturn.ColorOperation = renderBreak.ColorOperation; toReturn.BlendOperation = renderBreak.BlendOperation; toReturn.TextureFilter = renderBreak.TextureFilter; toReturn.TextureAddressMode = renderBreak.TextureAddressMode; #if DEBUG toReturn.Details = renderBreak.Details; #endif toReturn.ObjectCausingBreak = renderBreak.ObjectCausingBreak; return(toReturn); }
public static RenderBreakViewModel FromRenderBreak(RenderBreak renderBreak) { RenderBreakViewModel toReturn = new RenderBreakViewModel(); toReturn.LayerName = renderBreak.LayerName; if (renderBreak.Texture != null) { toReturn.Texture = renderBreak.Texture.Name; } toReturn.ColorOperation = renderBreak.ColorOperation; toReturn.BlendOperation = renderBreak.BlendOperation; toReturn.TextureFilter = renderBreak.TextureFilter; toReturn.TextureAddressMode = renderBreak.TextureAddressMode; #if DEBUG toReturn.Details = renderBreak.Details; #endif toReturn.ObjectCausingBreak = renderBreak.ObjectCausingBreak; return toReturn; }
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, false); 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)) { 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) 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) 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) { 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; } } #if !SILVERLIGHT Renderer.Texture = null; Renderer.TextureOnDevice = null; #endif if (section != null) { Section.EndContextAndTime(); } }
public void Draw(FlatRedBall.Camera camera) { ////////////////////////Early Out/////////////////////////////// if (DisableDrawing) { return; } //////////////////////End Early Out///////////////////////////// // This is the first call of the frame, so reset this value: SystemManagers.Default.Renderer.ClearPerformanceRecordingVariables(); if (FlatRedBall.Graphics.Renderer.CurrentLayer == null) { mManagers.TextManager.RenderTextTextures(); mManagers.Draw(mManagers.Renderer.MainLayer); } else if (mFrbToGumLayers.ContainsKey(FlatRedBall.Graphics.Renderer.CurrentLayer)) { mManagers.Draw(mFrbToGumLayers[FlatRedBall.Graphics.Renderer.CurrentLayer]); } var renderBreaks = FlatRedBall.Graphics.Renderer.LastFrameRenderBreakList; if (renderBreaks != null) { // This object handles its own render breaks if (renderBreaks.Count != 0) { var last = renderBreaks.Last(); if (last.ObjectCausingBreak == this) { renderBreaks.RemoveAt(renderBreaks.Count - 1); } } foreach (var item in mManagers.Renderer.SpriteRenderer.LastFrameDrawStates) { foreach (var changeRecord in item.ChangeRecord) { var renderBreak = new RenderBreak(0, changeRecord.Texture, ColorOperation.Texture, BlendOperation.Regular, TextureAddressMode.Clamp); #if DEBUG renderBreak.ObjectCausingBreak = changeRecord.ObjectRequestingChange; #endif renderBreaks.Add(renderBreak); } } } mManagers.Renderer.ForceEnd(); }