public void Initialize() { mSection = new Section(); mSection.Name = "A"; mSection.Time = 100; for (int i = 0; i < 2; i++) { Section bSection = new Section(); bSection.Name = "B"; bSection.Time = 50; mSection.Children.Add(bSection); for (int j = 0; j < 2; j++) { Section cSection = new Section(); cSection.Name = "C"; cSection.Time = 25; bSection.Children.Add(cSection); } } mMergedSection = SectionMerger.Self.CreateMergedCopy(mSection); }
private static TreeNode CreateTreeNode(FlatRedBall.Performance.Measurement.Section subSection) { TreeNode treeNode = new TreeNode(); treeNode.Tag = subSection; SetTreeNodeText(subSection, treeNode); return(treeNode); }
private void AddTreeNodesFor(FlatRedBall.Performance.Measurement.Section section, TreeNodeCollection treeNodeCollection) { TreeNode mostExpensive = null; float mostExpensiveValue = -1; // so it is always smaller than even the smallest starting value: double timeOfSubSections = 0; List <TreeNode> list = new List <TreeNode>(); // This may be a revisited node: foreach (TreeNode node in treeNodeCollection) { list.Add(node); } foreach (var subSection in section.Children) { TreeNode treeNode = null; treeNode = CreateTreeNode(subSection); if (subSection.Time > mostExpensiveValue) { mostExpensive = treeNode; mostExpensiveValue = subSection.Time; } timeOfSubSections += subSection.Time; list.Add(treeNode); // adding tree nodes will just add times to existing // tree nodes if they already exist AddTreeNodesFor(subSection, treeNode.Nodes); } if (mostExpensive != null) { AppendTimeInMilliseconds(mostExpensive); } if (section.Time != 0) { double ratioAccountedFor = timeOfSubSections / section.Time; if (ratioAccountedFor < .98) { TreeNode node = new TreeNode(); node.Text = "???? " + (100 - ratioAccountedFor * 100).ToString("0.00") + "%"; list.Insert(0, node); } } treeNodeCollection.AddRange(list.ToArray()); }
Section GetSectionByName(string name, Section parent) { foreach (Section section in parent.Children) { if (section.Name == name) { return section; } } return null; }
public Section CreateMergedCopy(Section section) { Section toReturn = new Section(); toReturn.Name = section.Name; toReturn.Time = section.Time; DoMerge(section, toReturn); toReturn.SetParentRelationships(); return toReturn; }
private static void SetTreeNodeText(FlatRedBall.Performance.Measurement.Section subSection, TreeNode treeNode) { string percentage = "100%"; if (subSection.Parent != null) { float ratio = subSection.Time / subSection.Parent.Time; percentage = (ratio * 100).ToString("0.00") + "%"; } string text = subSection.Name + " " + percentage; treeNode.Text = text; }
private void DoMerge(Section original, Section merged) { foreach (Section section in original.Children) { Section existingSection = GetSectionByName(section.Name, merged); if (existingSection == null) { existingSection = new Section(); existingSection.Name = section.Name; existingSection.Time = section.Time; merged.Children.Add(existingSection); } else { existingSection.Time += section.Time; } DoMerge(section, existingSection); } }
private static void DrawUnlayeredObjects(Camera camera, RenderMode renderMode, Section section) { CurrentLayer = null; if (section != null) { Section.GetAndStartContextAndTime("Draw above shapes"); } #region Draw Shapes if UnderEverything if (camera.DrawsWorld && renderMode == RenderMode.Default && camera.DrawsShapes && ShapeManager.ShapeDrawingOrder == FlatRedBall.Math.Geometry.ShapeDrawingOrder.UnderEverything) { // Draw shapes DrawShapes( camera, ShapeManager.mSpheres, ShapeManager.mCubes, ShapeManager.mRectangles, ShapeManager.mCircles, ShapeManager.mPolygons, ShapeManager.mLines, ShapeManager.mCapsule2Ds, null ); } #endregion //TimeManager.SumTimeSection("Draw models"); #region Draw ZBuffered Sprites and Mixed // Only draw the rest if in default rendering mode if (renderMode == RenderMode.Default) { if (camera.DrawsWorld) { if (section != null) { Section.EndContextAndTime(); Section.GetAndStartContextAndTime("Draw Z Buffered Sprites"); } if (SpriteManager.ZBufferedSpritesWriteable.Count != 0) { #if WINDOWS_PHONE || MONOGAME // Note, this means that we can't use the "Color" color operation. // For PC we do clip() in the shader. We can't do that on WP7 so we use an alpha test effect SetCurrentEffect(mAlphaTestEffect, camera); #endif // Draw the Z Buffered Sprites DrawZBufferedSprites(camera, SpriteManager.ZBufferedSpritesWriteable); #if WINDOWS_PHONE || MONOGAME SetCurrentEffect(mEffect, camera); #endif } foreach (var drawableBatch in SpriteManager.mZBufferedDrawableBatches) { if (drawableBatch.UpdateEveryFrame) { drawableBatch.Update(); } drawableBatch.Draw(camera); } if (section != null) { Section.EndContextAndTime(); Section.GetAndStartContextAndTime("Draw Ordered objects"); } // Draw the OrderedByDistanceFromCamera Objects (Sprites, Texts, DrawableBatches) DrawOrderedByDistanceFromCamera(camera, section); } } #endregion if (section != null) { Section.EndContextAndTime(); Section.GetAndStartContextAndTime("Draw below shapes"); } #region Draw Shapes if OverEverything if (camera.DrawsWorld && renderMode == RenderMode.Default && camera.DrawsShapes && ShapeManager.ShapeDrawingOrder == ShapeDrawingOrder.OverEverything) { // Draw shapes DrawShapes( camera, ShapeManager.mSpheres, ShapeManager.mCubes, ShapeManager.mRectangles, ShapeManager.mCircles, ShapeManager.mPolygons, ShapeManager.mLines, ShapeManager.mCapsule2Ds, null ); } #endregion //TimeManager.SumTimeSection("Draw ZBuffered and Mixed"); if (section != null) { Section.EndContextAndTime(); } }
private static void DrawLayers(Camera camera, RenderMode renderMode, Section section) { //TimeManager.SumTimeSection("Set device settings"); #region Draw World Layers // Draw layers that belong to the World "SpriteEditor" if (camera.DrawsWorld) { // These layers are still considered in the "world" because all // Cameras can see them. for (int i = 0; i < SpriteManager.LayersWriteable.Count; i++) { Layer layer = SpriteManager.LayersWriteable[i]; DrawIndividualLayer(camera, renderMode, layer, section); } } #endregion //TimeManager.SumTimeSection("Draw World Layers"); #region Draw Camera Layers if (camera.DrawsCameraLayer) { int layerCount = camera.Layers.Count; for (int i = 0; i < layerCount; i++) { Layer layer = camera.Layers[i]; DrawIndividualLayer(camera, renderMode, layer, section); } } #endregion //TimeManager.SumTimeSection("Draw Camera Layers"); #region Last, draw the top layer if (camera.DrawsWorld && !SpriteManager.TopLayer.IsEmpty) { Layer layer = SpriteManager.TopLayer; DrawIndividualLayer(camera, renderMode, layer, section); } #endregion //TimeManager.SumTimeSection("Last, draw the top layer"); }
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(); } }
private static void DrawOrderedByDistanceFromCamera(Camera camera, Section section) { if (SpriteManager.OrderedByDistanceFromCameraSprites.Count != 0 || SpriteManager.WritableDrawableBatchesList.Count != 0 || TextManager.mDrawnTexts.Count != 0) { Renderer.CurrentLayer = null; // Draw DrawMixed( SpriteManager.OrderedByDistanceFromCameraSprites, SpriteManager.OrderedSortType, TextManager.mDrawnTexts, SpriteManager.WritableDrawableBatchesList, false, camera, section); } }
static void DrawCamera(Camera camera, RenderMode renderMode, Section section) { if (section != null) { Section.GetAndStartContextAndTime("Start of camera draw"); } PrepareForDrawScene(camera, renderMode); if (section != null) { Section.EndContextAndTime(); Section.GetAndStartContextAndTime("Draw UnderAllLayer"); } if (camera.DrawsWorld && !SpriteManager.UnderAllDrawnLayer.IsEmpty) { Layer layer = SpriteManager.UnderAllDrawnLayer; DrawIndividualLayer(camera, RenderMode.Default, layer, section); } if (section != null) { Section.EndContextAndTime(); Section.GetAndStartContextAndTime("Draw Unlayered"); } DrawUnlayeredObjects(camera, renderMode, section); // Draw layers - this method will check internally for the camera's DrawsWorld and DrawsCameraLayers properties if (section != null) { Section.EndContextAndTime(); Section.GetAndStartContextAndTime("Draw Regular Layers"); } DrawLayers(camera, renderMode, section); if (section != null) { Section.EndContextAndTime(); } }
public static void DrawCamera(Camera camera, Section section) { DrawCamera(camera, RenderMode.Default, section); }
private static void DrawIndividualLayer(Camera camera, RenderMode renderMode, Layer layer, Section section) { bool hasLayerModifiedCamera = false; if (layer.Visible) { Renderer.CurrentLayer = layer; if (section != null) { string layerName = "No Layer"; if(layer != null) { layerName = layer.Name; } Section.GetAndStartContextAndTime("Layer: " + layerName); } ClearBackgroundForLayer(camera); #region Set View and Projection // Store the camera's FieldOfView in the oldFieldOfView and // set the camera's FieldOfView to the layer's OverridingFieldOfView // if necessary. mOldCameraLayerSettings.SetFromCamera(camera); Vector3 oldPosition = camera.Position; if (layer.LayerCameraSettings != null) { layer.LayerCameraSettings.ApplyValuesToCamera(camera, SetCameraOptions.PerformZRotation, null); hasLayerModifiedCamera = true; } camera.SetDeviceViewAndProjection(mCurrentEffect, layer.RelativeToCamera); #endregion if (renderMode == RenderMode.Default) { if (layer.mZBufferedSprites.Count > 0) { DrawZBufferedSprites(camera, layer.mZBufferedSprites); } // Draw the camera's layer DrawMixed(layer.mSprites, layer.mSortType, layer.mTexts, layer.mBatches, layer.RelativeToCamera, camera, section); #region Draw Shapes DrawShapes(camera, layer.mSpheres, layer.mCubes, layer.mRectangles, layer.mCircles, layer.mPolygons, layer.mLines, layer.mCapsule2Ds, layer); #endregion } // Set the Camera's FieldOfView back // Vic asks: What if the user wants to have a wacky field of view? // Does that mean that this will regulate it on layers? This is something // that may need to be fixed in the future, but it seems rare and will bloat // the visible property list considerably. Let's leave it like this for now // to establish a pattern then if the time comes to change this we'll be comfortable // with the overriding field of view pattern so a better decision can be made. if (hasLayerModifiedCamera) { mOldCameraLayerSettings.ApplyValuesToCamera(camera, SetCameraOptions.ApplyMatrix, layer.LayerCameraSettings); camera.Position = oldPosition; } if (section != null) { Section.EndContextAndTime(); } } }
//public static Section GetAndStartContext(string name) //{ // Section section = new Section(); // section.Name = name; // section.StartContext(); // return section; //} //public static Section GetAndStartTime(string name) //{ // Section section = new Section(); // section.Name = name; // section.StartTime(); // return section; //} public static Section GetAndStartContextAndTime(string name) { Section section = new Section(); section.Name = name; section.StartContext(); section.StartTime(); return section; }
public void StartContext() { mContext = this; }
public void EndContext() { if (mContext == this) { mContext = this.Parent; } else { string message = "This Section is not the context, so it can't end it."; if(mContext == null) { message += "Current context is null"; } else { message += "Current context is " + mContext.Name; } throw new Exception(message); } }