public void Draw(Texture2D texture, RectangleF targetRectangle, RectangleF?sourceRectangle, Color color, Vector2 origin, QuadEffects effects, float layerDepth) { PrepareGroup(); if (targetRectangle.Width == 0 || targetRectangle.Height == 0) { // Empty draw, ignore it return; } var bounds = texture.Bounds; var s = new Vector2I(bounds.Width, bounds.Height); var entry = new BatchEntry(); entry.Texture = texture; entry.Color = color; entry.SourceRect = sourceRectangle ?? new RectangleF(0, 0, s.X, s.Y); entry.Origin = origin; entry.SpriteEffects = effects; entry.Transform = Matrix.CreateScale(targetRectangle.Width / entry.SourceRect.Width, targetRectangle.Height / entry.SourceRect.Height, 1.0f) * Matrix.CreateTranslation(targetRectangle.X, targetRectangle.Y, 0); currentBatch.Entries.Add(entry); }
public void Draw(DrawArgs args) { Vector3 c_pos = CameraManager.Current.position; float c_dist = (float)(Math.Pow(args.Position.X - c_pos.X, 2) + Math.Pow(args.Position.Y - c_pos.Y, 2) + Math.Pow(args.Position.Y - c_pos.Y, 2)); BatchEntry r = new BatchEntry(this, c_dist, (DrawArgs)args.Clone()); BatchManager.Current.Add(r); }
private static void CreateBatchAction(BatchEntry batch, int durationOverride) { PageStorage <ManualActionExecutionData> .Instance.StorageData.Name = batch.Name; PageStorage <ManualActionExecutionData> .Instance.StorageData.ExecutionList = new List <ManualActionExecutionData.ManualActionExecution>() { new ManualActionExecutionData.ManualActionExecution(batch.ChannelId, batch.Duration, batch.ActivateMasterChannel, durationOverride) }; PageStorage <ManualActionExecutionData> .Instance.Save(); PageStorage <ManualActionExecutionData> .Instance.StorageData.Name = ""; PageStorage <ManualActionExecutionData> .Instance.StorageData.ExecutionList = null; }
public void Draw(FontLayout layout) { PrepareGroup(); if (layout.Layout.Count == 0) { return; } var areaSize = layout.Area.Size; Vector2 origin = Vector2.Zero; switch (layout.Alignment) { case AlignmentType.NorthWest: break; case AlignmentType.SouthWest: origin.Y = areaSize.Y; break; case AlignmentType.West: origin.Y = areaSize.Y / 2; break; case AlignmentType.Center: origin = areaSize / 2; break; case AlignmentType.North: origin.X = areaSize.X / 2; break; case AlignmentType.NorthEast: origin.X = areaSize.X; break; case AlignmentType.East: origin.X = areaSize.X; origin.Y = areaSize.Y / 2; break; case AlignmentType.SouthEast: origin.X = areaSize.X; origin.Y = areaSize.Y; break; case AlignmentType.South: origin.X = areaSize.X / 2; origin.Y = areaSize.Y; break; } foreach (var c in layout.Layout) { var entry = new BatchEntry(); entry.Texture = c.Texture; entry.Color = c.Color; entry.SourceRect = c.Source; entry.Origin = Vector2.Zero; entry.SpriteEffects = QuadEffects.RoundPositions; // TODO: Optimize entry.Transform = Matrix.CreateTranslation(-origin.X + c.Offset.X, -origin.Y + c.Offset.Y, 0) * Matrix.CreateScale(layout.Scale.X, layout.Scale.Y, 1) * Matrix.CreateTranslation(origin.X + layout.Position.X, origin.Y + layout.Position.Y, 0); currentBatch.Entries.Add(entry); } }
/// <summary> /// /// </summary> /// <param name="text"></param> /// <param name="position"></param> /// <param name="cameraZoom"></param> /// <param name="font"></param> /// <param name="textColor"></param> /// <param name="outlineColor"></param> /// <param name="outlineWidth"></param> /// <param name="clipRect">Rect to clip against. Note this will be inflated to compensate for outline width.</param> /// <param name="scaling"></param> /// <returns></returns> public static BatchEntry CreateEntry(string text, Vector2 position, float cameraZoom, SystemFont font, Color textColor, Color outlineColor = default(Color), float outlineWidth = 0, RectangleF clipRect = default(RectangleF), Vector2 scaling = default(Vector2)) { BatchEntry entry = null; if (freeEntries.Count > 0) { entry = freeEntries[freeEntries.Count - 1]; freeEntries.RemoveAt(freeEntries.Count - 1); } else { entry = new BatchEntry(); } if (scaling == default(Vector2)) { scaling = Vector2.One; } entry.cameraZoom = cameraZoom; entry.scaling = scaling; entry.text = text; // Adjust position for cameraZoom and outline thickness. entry.position = cameraZoom * position; entry.font = font; entry.textColor = textColor; Vector2 textSize = font.MeasureString(text); entry.size = new SizeF(textSize.X + 2.0f * cameraZoom * outlineWidth, textSize.Y); if (clipRect == default(RectangleF)) { // No clipRect was given so make one to fit the text. entry.clipRect = new System.Drawing.RectangleF(position.X * cameraZoom, position.Y * cameraZoom, entry.size.Width, entry.size.Height); } else { entry.clipRect = new System.Drawing.RectangleF(clipRect.X * cameraZoom, clipRect.Y * cameraZoom, clipRect.Width * cameraZoom, clipRect.Height * cameraZoom); } // Inflate clipRect to account for outline width. entry.clipRect.Inflate(cameraZoom * outlineWidth, cameraZoom * outlineWidth); entry.outlineColor = outlineColor; entry.outlineWidth = outlineWidth; return(entry); } // end of CreateEntry()
public void Draw(Texture2D texture, Matrix transform, Color color, Vector2 origin, float layerDepth) { PrepareGroup(); var bounds = texture.Bounds; var s = new Vector2I(bounds.Width, bounds.Height); var entry = new BatchEntry(); entry.Texture = texture; entry.Color = color; entry.SourceRect = new RectangleF(0, 0, s.X, s.Y); entry.Transform = transform; entry.Origin = origin; currentBatch.Entries.Add(entry); }
} // end of StartBatch() /// <summary> /// /// </summary> /// <param name="text"></param> /// <param name="position">Position for rendering.</param> /// <param name="clipRect">Rect to clip text to.</param> /// <param name="font"></param> /// <param name="textColor"></param> /// <param name="scaling">Only applied to text, not rect.</param> /// <param name="outlineColor"></param> /// <param name="outlineWidth"></param> /// <returns></returns> public static Vector2 DrawString(string text, Vector2 position, RectangleF clipRect, SystemFont font, Color textColor, Vector2 scaling = default(Vector2), Color outlineColor = default(Color), float outlineWidth = 0) { Debug.Assert(inBatch, "You must call StartBatch() before this and EndBatch() when done."); if (scaling == default(Vector2)) { scaling = Vector2.One; } float zoom = camera != null ? camera.Zoom : 1.0f; if (zoom != 1.0f) { // Create a new version of the font matching the zoom. font = GetSystemFont(font.Font.Name, font.Font.Size * zoom, font.Font.Style); } BatchEntry entry = BatchEntry.CreateEntry(text, position, zoom, font, textColor, outlineColor, outlineWidth, clipRect, scaling); entries.Add(entry); return(new Vector2(entry.size.Width, entry.size.Height)); } // end of DrawString()
public BatchPage(BatchEntry batch, ManualPage parent) : base("div") { const int labelSize = 100; _batch = batch; SetBorder(BorderKind.Rounded, StylingColor.Secondary); #region Initialize Grid Grid grid = new Grid(this); grid.AddStyling(StylingOption.MarginRight, 2); grid.AddStyling(StylingOption.MarginLeft, 2); grid.AddStyling(StylingOption.MarginTop, 4); grid.AddStyling(StylingOption.MarginBottom, 2); #endregion Initialize Grid #region JobName MultiInputGroup batchNameMultiInputGroup = new MultiInputGroup(); batchNameMultiInputGroup.AppendLabel("BatchName", labelSize); StylableTextInput batchNameTextInput = batchNameMultiInputGroup.AppendTextInput("Name?", startText: batch.Name); batchNameMultiInputGroup.AppendValidation("", "Ein Batch-Auftrag mit diesem Namen existiert bereits", false); batchNameMultiInputGroup.AppendCustomElement(new Button(StylingColor.Success, asOutline: true, text: "Namen übernehmen", fontAwesomeIcon: "save"), false).Click += (sender, args) => { if (batchNameTextInput.Value == "") { batchNameTextInput.SetValidation(false, true); return; } if (PageStorage <ManualData> .Instance.StorageData.BatchEntries.Any(entry => entry.Name == batchNameTextInput.Value)) { if (batch.Name == batchNameTextInput.Value) { return; } else { batchNameTextInput.SetValidation(false, true); } } else { batchNameTextInput.SetValidation(true, false); foreach (BatchEntry entry in PageStorage <ManualData> .Instance.StorageData.JobEntries.SelectMany( entry => entry.BatchEntries.Where(batchEntry => batchEntry.Name == batch.Name && batchEntry != batch))) { entry.Name = batchNameTextInput.Value; } batch.Name = batchNameTextInput.Value; parent.UpdateBatch(); } }; Button deleteJobButton = batchNameMultiInputGroup.AppendCustomElement(new Button(StylingColor.Danger, asOutline: true, text: "Batch-Auftrag Löschen", fontAwesomeIcon: "trash"), false); deleteJobButton.Click += (sender, args) => { const string confirmMessage = "Wirklich Löschen"; if (deleteJobButton.Text != confirmMessage) { deleteJobButton.Text = confirmMessage; return; } else { PageStorage <ManualData> .Instance.StorageData.BatchEntries.Remove(batch); List <JobEntry> removeList = new List <JobEntry>(); foreach (JobEntry entry in PageStorage <ManualData> .Instance.StorageData.JobEntries.Where(entry => entry.BatchEntries.Any(batchEntry => batchEntry.Name == batch.Name))) { entry.BatchEntries.RemoveAll(batchEntry => batchEntry.Name == batch.Name); if (entry.BatchEntries.Count == 0) { removeList.Add(entry); } } foreach (JobEntry jobEntry in removeList) { PageStorage <ManualData> .Instance.StorageData.JobEntries.Remove(jobEntry); } parent.UpdateBatch(); parent.UpdateJobs(); } }; batchNameMultiInputGroup.AddStyling(StylingOption.MarginBottom, 2); grid.AddRow().AppendCollum(batchNameMultiInputGroup, autoSize: true); MultiInputGroup batchActionMultiInputGroup = new MultiInputGroup(); batchActionMultiInputGroup.AppendLabel("Aktion", labelSize); batchActionMultiInputGroup.AppendLabel(batch.ToString()); batchActionMultiInputGroup.AddStyling(StylingOption.MarginBottom, 1); grid.AddRow().AppendCollum(batchActionMultiInputGroup, autoSize: true); #endregion JobName #region ExecuteAction #region Init Container Container firstContainer = new Container(); firstContainer.SetBorder(BorderKind.Rounded, StylingColor.Info); firstContainer.AddStyling(StylingOption.MarginTop, 3); firstContainer.AddStyling(StylingOption.MarginBottom, 1); firstContainer.AddStyling(StylingOption.PaddingTop, 3); firstContainer.AddStyling(StylingOption.PaddingBottom, 2); grid.AddRow().AppendCollum(firstContainer, autoSize: true); #endregion Init Container #region create Heading Heading firstHeading = new Heading(5, "Batch Ausführen ..."); firstContainer.AppendChild(firstHeading); #endregion create Heading #region Override OverrideInputGroup overrideInputGroup = new OverrideInputGroup(100); firstContainer.AppendChild(overrideInputGroup); #endregion Override #region StartButton Button startButton = new Button(StylingColor.Success, true, text: "Einreihen!", fontAwesomeIcon: "plus-circle", asBlock: true); firstContainer.AppendChild(startButton); startButton.Click += (o, args) => { startButton.IsDisabled = true; try { CreateBatchAction(batch, overrideInputGroup.Value); startButton.Text = "Wurde Eingereiht"; Task.Run(() => { System.Threading.Thread.Sleep(5000); startButton.Text = "Einreihen!"; startButton.SetFontAwesomeIcon("plus-circle"); return(startButton.IsDisabled = false); }); } catch (Exception) { startButton.Text = "Einreihen fehlgeschlagen"; throw; } }; firstContainer.AppendChild(startButton); startButton.AddStyling(StylingOption.MarginBottom, 2); #endregion StartButton #endregion ExecuteAction #region AddToJob #region Init Container Container secondContainer = new Container(); secondContainer.SetBorder(BorderKind.Rounded, StylingColor.Info); secondContainer.AddStyling(StylingOption.MarginTop, 3); secondContainer.AddStyling(StylingOption.MarginBottom, 1); secondContainer.AddStyling(StylingOption.PaddingTop, 3); secondContainer.AddStyling(StylingOption.PaddingBottom, 2); grid.AddRow().AppendCollum(secondContainer, autoSize: true); #endregion Init Container #region create Heading Heading heading = new Heading(5, "... zu Job-Auftrag hinzufügen"); secondContainer.AppendChild(heading); #endregion create Heading #region JobName Input _jobNameMultiInputGroup = new MultiInputGroup(); _jobNameMultiInputGroup.AddStyling(StylingOption.MarginTop, 4); _jobNameMultiInputGroup.AppendLabel("Name für den Job-Auftrag:"); StylableTextInput jobNameTextInput = _jobNameMultiInputGroup.AppendTextInput("Name?"); _jobNameMultiInputGroup.AppendValidation("", "Es gibt bereits einen Job mit diesem Namen", false); _jobNameMultiInputGroup.IsHidden = true; secondContainer.AppendChild(_jobNameMultiInputGroup); #endregion JobName Input #region jobSelect MultiInputGroup jobSelectMultiInputGroup = new MultiInputGroup(); jobSelectMultiInputGroup.AddStyling(StylingOption.MarginTop, 4); jobSelectMultiInputGroup.AppendLabel("Ziel Job:"); _jobSelectDropdown = jobSelectMultiInputGroup.AppendCustomElement(new Dropdown(new Button(StylingColor.Secondary, true, text: "Bitte Wählen!"), DropdownDirection.DropDown), false); FillJobDropDown(); jobSelectMultiInputGroup.AppendValidation("", "Dieser Batch-Auftrag ist bereits Bestandteil des Jobs", true); secondContainer.AppendChild(jobSelectMultiInputGroup); #endregion jobSelect #region Appent To Job or Create New _appendToJobButton = new Button(StylingColor.Success, true, text: "Zu Job-Auftrag hinzufügen", fontAwesomeIcon: "save", asBlock: true); _appendToJobButton.AddStyling(StylingOption.MarginTop, 2); _appendToJobButton.Click += (sender, args) => { if (batchNameTextInput.Value == "") { jobNameTextInput.SetValidation(false, true); return; } if (_jobSelectDropdown.Button.Text == NewJobString) { if (PageStorage <ManualData> .Instance.StorageData.JobEntries.Any(entry => entry.Name == jobNameTextInput.Value) || jobNameTextInput.Value == "") { // Invalid entered Name jobNameTextInput.SetValidation(false, true); } else { // Create Job jobNameTextInput.SetValidation(true, false); PageStorage <ManualData> .Instance.StorageData.JobEntries.Add(new JobEntry(jobNameTextInput.Value, batch)); parent.UpdateJobs(); _jobNameMultiInputGroup.IsHidden = true; _jobSelectDropdown.Button.Text = jobNameTextInput.Value; _appendToJobButton.IsHidden = true; _removeFromJobButton.IsHidden = false; } } else { jobNameTextInput.SetValidation(false, false); // Add To Job PageStorage <ManualData> .Instance.StorageData.JobEntries.First(entry => entry.Name == _jobSelectDropdown.Button.Text).BatchEntries.Add(batch); parent.UpdateJobs(); _appendToJobButton.IsHidden = true; _removeFromJobButton.IsHidden = false; } }; secondContainer.AppendChild(_appendToJobButton); #endregion Appent To Job or Create New #region Remove From Job _removeFromJobButton = new Button(StylingColor.Danger, true, text: "Aus Job löschen", fontAwesomeIcon: "trash", asBlock: true); _removeFromJobButton.AddStyling(StylingOption.MarginTop, 2); _removeFromJobButton.IsHidden = true; _removeFromJobButton.Click += (sender, args) => { if (PageStorage <ManualData> .Instance.StorageData.JobEntries.Any(entry => entry.Name == _jobSelectDropdown.Button.Text)) { JobEntry jobEntry = PageStorage <ManualData> .Instance.StorageData.JobEntries.First(entry => entry.Name == _jobSelectDropdown.Button.Text); jobEntry.BatchEntries.RemoveAll(entry => entry.Name == _batch.Name); if (jobEntry.BatchEntries.Count == 0) { PageStorage <ManualData> .Instance.StorageData.JobEntries.Remove(jobEntry); } } _removeFromJobButton.IsHidden = true; _appendToJobButton.IsHidden = false; FillJobDropDown(); parent.UpdateJobs(); }; secondContainer.AppendChild(_removeFromJobButton); #endregion Remove From Job #endregion AddToJob }
private void Render(RenderQueue.Batch renderBatch) { var batch = (Batch)renderBatch; var entries = batch.Entries; if (entries.Count > 0) { RenderHelpers.SetBlendMode(blendMode); GL.Disable(EnableCap.CullFace); GL.Disable(EnableCap.DepthTest); //GL.Viewport(graphicsDevice.Viewport.X, graphicsDevice.BackBufferSize.Y - graphicsDevice.Viewport.Y - graphicsDevice.Viewport.Height, graphicsDevice.Viewport.Width, graphicsDevice.Viewport.Height); currentEffect.Projection = Projection ?? CurrentContext.ActiveScreen.DefaultProjection; currentEffect.View = transform; currentEffect.Enable(); for (int i = 0; i < entries.Count;) { int quadIndex = 0; BatchEntry firstEntry = entries[i]; Texture2D texture = firstEntry.Texture; if (AddEntry(ref firstEntry, quadIndex++) == 0) { Debug.WriteLine("Warning: out of QuadBatch capacity!"); break; } // Push in new quads until we reach a new texture int entryCount = 1; for (int j = i + 1; j < entries.Count; ++j) { BatchEntry futureEntry = entries[j]; if (futureEntry.Texture != texture) { break; } int added = AddEntry(ref futureEntry, quadIndex++); if (added == 0) { Debug.WriteLine("Warning: out of QuadBatch capacity!"); } entryCount += added; // If we're out of entry slots, do not increase entryCount } // Set texture GL.BindTexture(TextureTarget.Texture2D, texture.textureId); RenderHelpers.SetSamplers(textureSampling); GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBufferObjects[0]); GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(entryCount * 6 * Vertex2Tex2Color.GetSize()), quads, BufferUsageHint.DynamicDraw); //GL.BufferSubData(BufferTarget.ArrayBuffer, IntPtr.Zero, (IntPtr)(entryCount * 6 * Vertex2Tex2Color.GetSize()), quads); GL.BindBuffer(BufferTarget.ElementArrayBuffer, vertexBufferObjects[1]); if (currentEffect.ColorAttribute.HasValue) { GL.VertexAttribPointer(currentEffect.ColorAttribute.Value, 4, VertexAttribPointerType.UnsignedByte, true, Vertex2Tex2Color.GetSize(), sizeof(float) * 2); } GL.VertexAttribPointer(currentEffect.VertexAttribute, 2, VertexAttribPointerType.Float, false, Vertex2Tex2Color.GetSize(), 0); GL.VertexAttribPointer(currentEffect.TextureCoordinatesAttribute, 2, VertexAttribPointerType.Float, false, Vertex2Tex2Color.GetSize(), sizeof(float) * 2 + sizeof(byte) * 4); GL.DrawElements(BeginMode.Triangles, entryCount * 6, DrawElementsType.UnsignedShort, 0); i += entryCount; } entries.Clear(); currentEffect.Disable(); GL.BindBuffer(BufferTarget.ArrayBuffer, 0); GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0); } // This group is done, recycle it to the pool batchPool.Delete(batch); }
private int AddEntry(ref BatchEntry entry, int quadIndex) { if (quadIndex >= capacity) { return(0); } float contentScale = 1.0f; float w = entry.SourceRect.Width; float h = entry.SourceRect.Height; var bounds = entry.Texture.Bounds; Vector2I realSize = new Vector2I(bounds.Width, bounds.Height); float atlasWidth = realSize.X; float atlasHeight = realSize.Y; Quad q = new Quad(); Vector2 topLeft = new Vector2(-entry.Origin.X, -entry.Origin.Y); Vector2 topRight = new Vector2(topLeft.X + w, topLeft.Y); Vector2 bottomLeft = new Vector2(topLeft.X, topLeft.Y + h); Vector2 bottomRight = new Vector2(topLeft.X + w, topLeft.Y + h); topLeft = Vector2.Transform(topLeft, entry.Transform); topRight = Vector2.Transform(topRight, entry.Transform); bottomLeft = Vector2.Transform(bottomLeft, entry.Transform); bottomRight = Vector2.Transform(bottomRight, entry.Transform); q.TopLeft.Position = topLeft; q.TopRight.Position = topRight; q.BottomLeft.Position = bottomLeft; q.BottomRight.Position = bottomRight; if ((entry.SpriteEffects & QuadEffects.RoundPositions) != 0) { q.TopLeft.Position.X = (int)q.TopLeft.Position.X; q.TopLeft.Position.Y = (int)q.TopLeft.Position.Y; q.TopRight.Position.X = (int)q.TopRight.Position.X; q.TopRight.Position.Y = (int)q.TopRight.Position.Y; q.BottomLeft.Position.X = (int)q.BottomLeft.Position.X; q.BottomLeft.Position.Y = (int)q.BottomLeft.Position.Y; q.BottomRight.Position.X = (int)q.BottomRight.Position.X; q.BottomRight.Position.Y = (int)q.BottomRight.Position.Y; } q.TopLeft.Color = entry.Color; q.TopRight.Color = entry.Color; q.BottomLeft.Color = entry.Color; q.BottomRight.Color = entry.Color; float left, right, top, bottom; { left = entry.SourceRect.X * contentScale / atlasWidth; right = left + entry.SourceRect.Width * contentScale / atlasWidth; top = entry.SourceRect.Y * contentScale / atlasHeight; bottom = top + entry.SourceRect.Height * contentScale / atlasHeight; if ((entry.SpriteEffects & QuadEffects.FlipHorizontally) != 0) { var temp = left; left = right; right = temp; } if ((entry.SpriteEffects & QuadEffects.FlipVertically) != 0) { var temp = top; top = bottom; bottom = temp; } q.BottomLeft.TextureCoordinate.X = left; q.BottomLeft.TextureCoordinate.Y = bottom; q.BottomRight.TextureCoordinate.X = right; q.BottomRight.TextureCoordinate.Y = bottom; q.TopLeft.TextureCoordinate.X = left; q.TopLeft.TextureCoordinate.Y = top; q.TopRight.TextureCoordinate.X = right; q.TopRight.TextureCoordinate.Y = top; } quads[quadIndex] = q; return(1); }