public override void Draw(RenderComposer composer) { Color textCol = new Color(32, 32, 32); int size = 20; string text = "The quick brown fox jumped over the lazy dog."; composer.SetUseViewMatrix(false); composer.RenderSprite(new Vector3(0, 0, 0), Engine.Renderer.CurrentTarget.Size, new Color(240, 240, 240)); composer.PushModelMatrix(Matrix4x4.CreateScale(1, 1, 1) * Matrix4x4.CreateTranslation(100, 100, 0)); FontAsset.GlyphRasterizer = GlyphRasterizer.Emotion; composer.RenderLine(new Vector3(0, 0, 0), new Vector3(500, 0, 0), Color.Red); composer.RenderString(new Vector3(0, 0, 0), textCol, "Emotion Renderer:\n" + text, _font.GetAtlas(size)); FontAsset.GlyphRasterizer = GlyphRasterizer.EmotionSDFVer3; composer.RenderLine(new Vector3(0, 140, 0), new Vector3(500, 140, 0), Color.Red); composer.RenderString(new Vector3(0, 140, 0), textCol, "EmotionSDFVer3:\n" + text, _font.GetAtlas(size)); FontAsset.GlyphRasterizer = GlyphRasterizer.EmotionSDFVer4; composer.RenderLine(new Vector3(0, 300, 0), new Vector3(500, 300, 0), Color.Red); composer.RenderString(new Vector3(0, 300, 0), textCol, "EmotionSDFVer4:\n" + text, _font.GetAtlas(size)); FontAsset.GlyphRasterizer = GlyphRasterizer.StbTrueType; composer.RenderLine(new Vector3(0, 450, 0), new Vector3(500, 450, 0), Color.Red); composer.RenderString(new Vector3(0, 450, 0), textCol, "StbTrueType:\n" + text, _font.GetAtlas(size)); composer.PopModelMatrix(); composer.SetUseViewMatrix(true); }
public void Draw(RenderComposer composer) { // The vertices were taken from a font, and the polygon is huge. composer.PushModelMatrix(Matrix4x4.CreateScale(0.1f, 0.1f, 1f)); composer.SetStencilTest(true); composer.StencilWindingStart(); composer.ToggleRenderColor(false); // Draw all of them together. Winding will take care of the overlap. var accum = Rectangle.Empty; for (var i = 0; i < _testPolygon.Length; i++) { composer.RenderVertices(_testPolygon[i].Vertices, Color.White); accum = accum.Union(_testPolygon[i].Bounds2D); } composer.StencilWindingEnd(); composer.ToggleRenderColor(true); // You need one quad which covers the bounds of all the polygons. // In this case I added the bounding boxes, but you could just draw a screen sized quad. composer.RenderSprite(accum, Color.Red); composer.SetStencilTest(false); composer.PopModelMatrix(); }
public override void Render(RenderComposer composer) { if (InclineAngle != 0f) { composer.PushModelMatrix( Matrix4x4.CreateRotationZ(InclineAngle, new Vector3(Center, 0)) ); } composer.RenderSprite( Position, Size, !IsAffectedByGravityPush ? Color.White : Color.Pink, TextureAsset.Texture, null, IsFacingRight ); if (InclineAngle != 0f) { composer.PopModelMatrix(); } if (IsInteracting) { string text = Dialogues[0].DialogueLines[0]; composer.RenderString(Position + new Vector3(-30, -30, 0), Color.Black, text, Engine.AssetLoader.Get <FontAsset>("Fonts/Calibri 400.ttf").GetAtlas(16)); } //Rectangle futurePosition = new Rectangle(CollisionBox.X, CollisionBox.Y - (GravityTimer.Progress * StartingVelocityY), CollisionBox.Width, CollisionBox.Height); //composer.RenderOutline(futurePosition, Color.Green, 1); //composer.RenderOutline(CollisionBox.ToRectangle(), Color.Red, 2); }
protected override bool RenderInternal(RenderComposer c) { if (Children == null || _awaitingLayout) { return(false); } Vector3 pos = c.Camera.WorldToScreen(_worldPos.ToVec2()).ToVec3(_worldPos.Z); c.PushModelMatrix(Matrix4x4.CreateTranslation(pos)); return(base.RenderInternal(c)); }
public override void Render(RenderComposer composer) { if (TextureAsset == null) { return; } if (BlurIntensity > 0) { // Apply Blur effect if such is set composer.SetShader(BlurShader.Shader); BlurShader.Shader.SetUniformFloat("sigma", BlurIntensity); } Color color = Color.White; if (ShadowReverseIntensity < 255) { // Apply Shadow effect if such is set color = new Color(ShadowReverseIntensity, ShadowReverseIntensity, ShadowReverseIntensity); // 180 for a shadowy look } if (Rotation != 0f) { // Apply rotation if such is set // Tiled rotates images around the bottom left corner composer.PushModelMatrix( Matrix4x4.CreateRotationZ(Rotation, new Vector3(X, Y + DisplaySize.Y, 0)) ); } // Render composer.RenderSprite( Position, DisplaySize, color, TextureAsset.Texture, TextureArea, FlipX ); if (Rotation != 0f) { // Remove the rotation matrix composer.PopModelMatrix(); } if (BlurIntensity > 0) { // Remove the blur shader composer.SetShader(null); } }
public override void Render(RenderComposer composer) { // If she's in a magic flow render her as a circle if (IsMagicFlowActive) { composer.RenderCircle(CollisionBox.Center.ToVec3(Z), 15, Color.Pink, true); return; } // If walking on an incline apply rotation if (InclineAngle != 0f) { composer.PushModelMatrix( Matrix4x4.CreateRotationZ(InclineAngle, new Vector3(Center, 0)) ); } // Render the sprite composer.RenderSprite( Position, Size, !IsGravityPushActive ? Color.White : Color.Pink, Sprite.Texture, Sprite.CurrentFrame, IsFacingRight, false ); // Remove the rotation matrix if (InclineAngle != 0f) { composer.PopModelMatrix(); } if (IsGravityPushActive) { composer.RenderOutline( new Vector3( CollisionBox.Center.X - GravityPushRange, CollisionBox.Center.Y - GravityPushRange, 15 ), new Vector2(GravityPushRange * 2), Color.Pink, 2 ); } }
public void LineDrawing() { Runner.ExecuteAsLoop(_ => { RenderComposer composer = Engine.Renderer.StartFrame(); composer.PushModelMatrix(Matrix4x4.CreateTranslation(200, 200, 0)); // Diagonal Lines composer.RenderLine(new Vector3(10, 10, 0), new Vector3(50, 50, 0), Color.White); composer.RenderLine(new Vector3(50, 50, 0), new Vector3(100, 100, 0), Color.White, 2); composer.RenderLine(new Vector3(100, 100, 0), new Vector3(150, 150, 0), Color.White, 3); // Horizontal lines // 100 pixels long composer.RenderLine(new Vector3(100, 10, 0), new Vector3(200, 10, 0), Color.White); composer.RenderLine(new Vector3(100, 20, 0), new Vector3(200, 20, 0), Color.White, 2); composer.RenderLine(new Vector3(100, 30, 0), new Vector3(200, 30, 0), Color.White, 3); composer.RenderLine(new Vector3(100, 40, 0), new Vector3(200, 40, 0), Color.White, 4); // Vertical // 100 pixels high composer.RenderLine(new Vector3(10, 100, 0), new Vector3(10, 200, 0), Color.White); composer.RenderLine(new Vector3(20, 100, 0), new Vector3(20, 200, 0), Color.White, 2); composer.RenderLine(new Vector3(30, 100, 0), new Vector3(30, 200, 0), Color.White, 3); composer.RenderLine(new Vector3(40, 100, 0), new Vector3(40, 200, 0), Color.White, 4); // Test lines in all 2d directions. Z would only be visible with a 3d. camera. composer.RenderArrow(new Vector3(0, 0, 0), new Vector3(10, 0, 0), Color.Red); composer.RenderArrow(new Vector3(0, 0, 0), new Vector3(0, 10, 0), Color.Green); composer.RenderArrow(new Vector3(0, 0, 0), new Vector3(0, 0, 10), Color.Blue); // Lines must be at least 1 pixel thick. composer.RenderArrow(new Vector3(10, 0, 0), new Vector3(100, 0, 0), Color.Red, 0.1f); composer.RenderArrow(new Vector3(0, 10, 0), new Vector3(0, 100, 0), Color.Green, 0.1f); composer.RenderArrow(new Vector3(0, 0, 10), new Vector3(0, 0, 100), Color.Blue, 0.1f); composer.PopModelMatrix(); Engine.Renderer.EndFrame(); Runner.VerifyScreenshot(ResultDb.LineDrawing); }).WaitOne(); }
protected override void RenderContent(RenderComposer composer) { if (_explorer != null && _explorer.Open) { ImGui.Text("Waiting for file..."); return; } void ExecuteOnFile(Action <AudioTrack> func) { _explorer = new FileExplorer <AudioAsset>(asset => { var modifyModal = new AudioTrackModifyModal(asset, func); Parent.AddWindow(modifyModal); }, true); Parent.AddWindow(_explorer); } float masterVol = Engine.Configuration.MasterVolume; if (ImGui.DragFloat("Global Volume", ref masterVol, 0.01f, 0f, 1f)) { Engine.Configuration.MasterVolume = masterVol; foreach (KeyValuePair <AudioLayer, WaveformVisualization> cache in _waveFormCache) { cache.Value.Recreate(); } } bool mono = Engine.Configuration.ForceMono; if (ImGui.Checkbox("Force Mono", ref mono)) { Engine.Configuration.ForceMono = mono; } // Push waveforms down. composer.PushModelMatrix(Matrix4x4.CreateTranslation(new Vector3(0, 50, 0))); // Render ImGui section of layers. string[] layers = Engine.Audio.GetLayers(); for (var i = 0; i < layers.Length; i++) { AudioLayer layer = Engine.Audio.GetLayer(layers[i]); _waveFormCache.TryGetValue(layer, out WaveformVisualization cache); ImGui.PushID(i); ImGui.Text($"Layer: {layers[i]} [{layer.Status}] {(layer.CurrentTrack != null ? $" {MathF.Truncate(layer.Playback * 100f) / 100f:0}/{layer.CurrentTrack.File.Duration:0.0}s" : "")}"); float volume = layer.Volume; if (ImGui.DragFloat("Volume", ref volume, 0.01f, 0f, 1f)) { cache?.Recreate(); layer.Volume = volume; } if (ImGui.Button("Add To Queue")) { ExecuteOnFile(layer.AddToQueue); } ImGui.SameLine(); if (ImGui.Button("Add To Play Next")) { ExecuteOnFile(layer.PlayNext); } ImGui.SameLine(); if (ImGui.Button("Quick Play")) { ExecuteOnFile(layer.QuickPlay); } if (layer.Status == PlaybackStatus.Paused) { if (ImGui.Button("Resume")) { layer.Resume(); } } else { if (ImGui.Button("Pause")) { layer.Pause(); } } ImGui.SameLine(); ImGui.SameLine(); if (ImGui.Button("Stop")) { layer.Stop(); } ImGui.SameLine(); if (ImGui.Button("Toggle Loop")) { layer.LoopingCurrent = !layer.LoopingCurrent; } ImGui.SameLine(); ImGui.Text($"Looping: {layer.LoopingCurrent}"); string[] items = layer.Playlist.Select(x => x.Name).ToArray(); if (ImGui.TreeNode($"Playlist, Currently Playing: {(items.Length > 0 ? items[0] : "None")}")) { var r = 0; ImGui.ListBox("", ref r, items, items.Length); ImGui.TreePop(); } ImGui.Text($"Missed: {layer.MetricBackendMissedFrames}\nAhead: {layer.MetricDataStoredInBlocks}ms"); ImGui.PopID(); ImGui.NewLine(); composer.PushModelMatrix(Matrix4x4.CreateTranslation(new Vector3(10, i * (_waveFormHeight + 10), 0))); cache?.Render(composer); composer.PopModelMatrix(); } composer.PopModelMatrix(); ImGui.InputText("", ref _newLayerName, 50); ImGui.SameLine(); if (ImGui.Button("Create Layer") && !string.IsNullOrEmpty(_newLayerName)) { Engine.Audio.CreateLayer(_newLayerName); _newLayerName = "New Layer" + Engine.Audio.GetLayers().Length; } }
protected override void RenderContent(RenderComposer composer) { if (_explorer != null && _explorer.Open) { ImGui.Text("Waiting for file..."); return; } void ExecuteOnFile(Action <AudioTrack> func) { _explorer = new FileExplorer <AudioAsset>(asset => { var modifyModal = new AudioTrackModifyModal(asset, func); Parent.AddWindow(modifyModal); }); Parent.AddWindow(_explorer); } float masterVol = Engine.Configuration.MasterVolume; if (ImGui.DragFloat("Global Volume", ref masterVol, 0.01f, 0f, 1f)) { Engine.Configuration.MasterVolume = masterVol; foreach (KeyValuePair <AudioLayer, WaveformCache> cache in _waveFormCache) { cache.Value.Recreate(); } } // Push waveforms down. composer.PushModelMatrix(Matrix4x4.CreateTranslation(new Vector3(0, _waveFormHeight, 0))); // Render ImGui section of layers. string[] layers = Engine.Host.Audio.GetLayers(); for (var i = 0; i < layers.Length; i++) { AudioLayer layer = Engine.Host.Audio.GetLayer(layers[i]); _waveFormCache.TryGetValue(layer, out WaveformCache cache); ImGui.Text($"Layer {layers[i]}"); ImGui.PushID(i); ImGui.Text($"Status: {layer.Status}" + (layer.CurrentTrack != null ? $" {MathF.Truncate(layer.CurrentTrack.Playback * 100f) / 100f:0}/{layer.CurrentTrack.File.Duration}" : "")); float volume = layer.Volume; if (ImGui.DragFloat("Volume", ref volume, 0.01f, 0f, 1f)) { cache?.Recreate(); layer.Volume = volume; } if (ImGui.Button("Add To Queue")) { ExecuteOnFile(layer.AddToQueue); } ImGui.SameLine(); if (ImGui.Button("Play Next")) { ExecuteOnFile(layer.PlayNext); } ImGui.SameLine(); if (ImGui.Button("Quick Play")) { ExecuteOnFile(layer.QuickPlay); } if (ImGui.Button("Resume")) { layer.Resume(); } ImGui.SameLine(); if (ImGui.Button("Pause")) { layer.Pause(); } ImGui.SameLine(); if (ImGui.Button("Stop")) { layer.Stop(); } if (ImGui.Button("Loop Current")) { layer.LoopingCurrent = !layer.LoopingCurrent; } ImGui.SameLine(); ImGui.Text(layer.LoopingCurrent.ToString()); var r = 0; string[] items = layer.Playlist.Select(x => x.Name).ToArray(); ImGui.ListBox("Playlist", ref r, items, items.Length); ImGui.PopID(); ImGui.NewLine(); composer.PushModelMatrix(Matrix4x4.CreateTranslation(new Vector3(0, i * _waveFormHeight, 0))); cache?.Render(composer); composer.PopModelMatrix(); } composer.PopModelMatrix(); if (ImGui.Button("Create Layer") && !string.IsNullOrEmpty(_newLayerName)) { Engine.Host.Audio.CreateLayer(_newLayerName); _newLayerName = ""; } ImGui.InputText("", ref _newLayerName, 50); }
public static void RenderGlyphs(Font font, RenderComposer composer, List <DrawableGlyph> glyphs, Vector3 offset, uint clr, float scale, Rectangle[]?dstRects = null) { for (var c = 0; c < glyphs.Count; c++) { DrawableGlyph atlasGlyph = glyphs[c]; FontGlyph fontGlyph = atlasGlyph.FontGlyph; Rectangle dst = dstRects != null ? dstRects[c] : atlasGlyph.GlyphUV; if (CLIP_GLYPH_TEXTURES) { composer.SetClipRect(dst); } float baseline = font.Descender * scale; Vector3 atlasRenderPos = (dst.Position - new Vector2(atlasGlyph.XBearing, baseline)).ToVec3(); atlasRenderPos += offset; composer.PushModelMatrix(Matrix4x4.CreateScale(scale, scale, 1) * Matrix4x4.CreateTranslation(atlasRenderPos)); // Count vertices. GlyphDrawCommand[]? commands = fontGlyph.Commands; if (commands == null) { continue; } var verticesCount = 0; for (var v = 0; v < commands.Length; v++) { GlyphDrawCommand currentCommand = commands[v]; if (currentCommand.Type != GlyphDrawCommandType.Move) { verticesCount++; } } // Draw lines between all vertex points. Span <VertexData> lines = composer.RenderStream.GetStreamMemory((uint)(verticesCount * 3), BatchMode.SequentialTriangles); for (var j = 0; j < lines.Length; j++) { lines[j].UV = Vector2.Zero; lines[j].Color = clr; } Vector3 prevPos = Vector3.Zero; int currentContourStart = -1; var currentVertIdx = 0; for (var i = 0; i < commands.Length; i++) { GlyphDrawCommand currentCommand = commands[i]; if (currentContourStart == -1) { currentContourStart = i; } if (currentCommand.Type != GlyphDrawCommandType.Move) { Vector3 currentVertPos = currentCommand.P0.ToVec3(); if (currentCommand.Type == GlyphDrawCommandType.Close) { GlyphDrawCommand startingVert = commands[currentContourStart]; currentVertPos = startingVert.P0.ToVec3(); currentContourStart = -1; } lines[currentVertIdx].Vertex = Vector3.Zero; currentVertIdx++; lines[currentVertIdx].Vertex = currentVertPos; currentVertIdx++; lines[currentVertIdx].Vertex = prevPos; currentVertIdx++; } prevPos = currentCommand.P0.ToVec3(); } // Draw curves. These will flip pixels in the curve approximations from above. for (var i = 0; i < commands.Length; i++) { GlyphDrawCommand currentCommand = commands[i]; if (currentCommand.Type == GlyphDrawCommandType.Curve) { Span <VertexData> memory = composer.GetStreamedQuadraticCurveMesh(prevPos, currentCommand.P0.ToVec3(), currentCommand.P1.ToVec3()); for (var j = 0; j < memory.Length; j++) { memory[j].UV = Vector2.Zero; memory[j].Color = clr; } } prevPos = currentCommand.P0.ToVec3(); } composer.PopModelMatrix(); if (CLIP_GLYPH_TEXTURES) { composer.SetClipRect(null); } } }
///<summary> /// Render the object's Transform rectangle. /// Emotion specific method. ///</summary> public void RenderObjectRectange(RenderComposer composer) { // Check if Item can be cast to Unit in "unit" variable and if so provides the "unit" variable for further use if (Item is Unit unit) { // Draw texture center composer.RenderCircle(Item.Center.ToVec3(Item.Z), 3, Color.Green, true); if (unit.InclineAngle != 0f) { composer.PushModelMatrix( Matrix4x4.CreateRotationZ(unit.InclineAngle, new Vector3(unit.Center, 0)) ); } // Draw the texture rectangle composer.RenderOutline(Item.Position, Item.Size, Color.Green, 2); if (unit.InclineAngle != 0f) { composer.PopModelMatrix(); } // Draw future position for units Vector3 futurePosition; if (!unit.IsAffectedByGravityPush) { futurePosition = new Vector3( unit.CollisionBox.X + (unit.VelocityX * unit.RunTimer.Progress), unit.CollisionBox.Y - (unit.GravityTimer.Progress * unit.StartingVelocityY), unit.CollisionBox.Z ); } else { if (unit.GravityPushPushDurationTimer != null) { futurePosition = new Vector3( unit.CollisionBox.X + (unit.VelocityX * unit.GravityPushPushDurationTimer.Progress), unit.CollisionBox.Y - unit.StartingVelocityY, unit.CollisionBox.Z ); } else { futurePosition = new Vector3( unit.CollisionBox.X, unit.CollisionBox.Y - unit.StartingVelocityY, unit.CollisionBox.Z ); } } composer.RenderOutline(futurePosition, unit.CollisionBox.Size, Color.Cyan, 1); // Draw last position of the CollisionBox composer.RenderOutline(unit.LastState.CollisionBox.Position, unit.LastState.CollisionBox.Size, Color.Yellow, 2); // Draw CollisionBox for units composer.RenderOutline(unit.CollisionBox.Position, unit.CollisionBox.Size, Color.Red, 2); // Draw CollisionBox center for units composer.RenderCircle(unit.CollisionBox.Center.ToVec3(Item.Z), 3, Color.Red, true); } else if (Item is Decoration dec) { // Draw texture center composer.RenderCircle(Item.Center.ToVec3(Item.Z), 3, Color.Green, true); // Draw texture rectangle (without rotation) composer.RenderOutline(dec.Position, dec.DisplaySize, Color.Blue, 2); if (dec.Rotation != 0f) { // Tiled rotates images around the bottom left corner composer.PushModelMatrix( Matrix4x4.CreateRotationZ(dec.Rotation, new Vector3(dec.X, dec.Y + dec.DisplaySize.Y, 0)) ); } // Draw texture rectangle (with rotation) composer.RenderOutline(dec.Position, dec.DisplaySize, Color.Red, 2); if (dec.Rotation != 0f) { // Tiled rotates images around the bottom left corner composer.PopModelMatrix(); } } }