protected override void LoadContent() { _spriteBatch = new SpriteBatch(GraphicsDevice); _textureProvider = new TextureProvider(Content); _playingField = new PlayingFieldManager(_textureProvider, _graphics.GraphicsDevice.Viewport); SpriteBatchExtensions.LoadEffects(Content); }
public void DrawDebugInfo( ViewPortInfo viewPort, SpriteBatch spriteBatch, Rectangle destRectangle, SpriteFont spriteFont, float globalDispX, float globalDispY) { float actualBoxWidth = BoxWidth * viewPort.ActualZoom; float actualBoxHeight = BoxHeight * viewPort.ActualZoom; int startBoxX = (int)(globalDispX / actualBoxWidth); int startBoxY = (int)(globalDispY / actualBoxHeight); int viewBoxCountX = (int)Math.Ceiling(destRectangle.Width / actualBoxWidth) + 1; int viewBoxCountY = (int)Math.Ceiling(destRectangle.Height / actualBoxHeight) + 1; for (int i = 0; i < viewBoxCountX; i++) { for (int j = 0; j < viewBoxCountY; j++) { int I = i + startBoxX; int J = j + startBoxY; if (I < 0 || J < 0 || I >= _boxCountX || J >= _boxCountY) { continue; } int index = I + J * _boxCountX; int x = (int)(I * BoxWidth * viewPort.ActualZoom - globalDispX); int y = (int)(J * BoxHeight * viewPort.ActualZoom - globalDispY); int width = (int)(BoxWidth * viewPort.ActualZoom) - 1; int height = (int)(BoxHeight * viewPort.ActualZoom) - 1; int entityCount = _hashLists[index].Count; Color drawColor = debugColors[Math.Min(entityCount, debugColors.Length - 1)]; string debugText = string.Format("{0}\n\r{1}", index, entityCount); Vector2 debugTextMeasurements = spriteFont.MeasureString(debugText); SpriteBatchExtensions.DrawRectangle( spriteBatch, new Rectangle(x, y, width, height), drawColor, 0); if (debugTextMeasurements.X < width && debugTextMeasurements.Y < height) { SpriteBatchExtensions.DrawCenteredString( spriteBatch, spriteFont, debugText, new Vector2(x, y) + new Vector2(width, height) / 2, drawColor); } } } }
/// <summary> /// LoadContent will be called once per game and is the place to load /// all of your content. /// </summary> protected override void LoadContent() { // Initialize the SpriteBatchExtensions SpriteBatchExtensions.Initalize(this.GraphicsDevice); // Create a new SpriteBatch, which can be used to draw textures. _spriteBatch = new SpriteBatch(this.GraphicsDevice); _cursorSprite = this.Content.LoadTexture2D(Constants.FILEPATH_GFX + "cursor.png"); }
public override void Entry(IModHelper helper) { SpriteBatchExtensions.Init(this.Helper); this.manager = new WaveManager(this.Helper, this.Monitor); this.config = this.Helper.ReadConfig <ModConfig>(); this.Helper.Events.Display.Rendered += Display_Rendered; this.Helper.Events.Input.ButtonPressed += Input_ButtonPressed; this.Helper.Events.GameLoop.UpdateTicked += GameLoop_UpdateTicked; this.Helper.Events.Player.Warped += Player_Warped; this.Helper.Events.GameLoop.DayStarted += GameLoop_DayStarted; this.Helper.Events.GameLoop.ReturnedToTitle += GameLoop_ReturnedToTitle; this.Helper.Events.GameLoop.TimeChanged += GameLoop_TimeChanged; this.Helper.ConsoleCommands.Add("we", "Wind Effects console commands.\nUsage:\n\twe debug: enable/disable debugging", this.ConsoleCommand_Triggered); }
protected override void Draw(GameTime gameTime) { if (gameTime.TotalGameTime.TotalMilliseconds + GameConfig.Delta >= nextDraw) { GraphicsDevice.Clear(new Color(128, 174, 72)); spriteBatch.Begin(); foreach (CollisionRealm item in gameWorld.CollisionRealms) { SpriteBatchExtensions.DrawHollowRectangle(item.Area.Location, item.Area.Width, item.Area.Height, 2, Color.Gray); item.CollisionRealmId.ToString().DrawString(new Vector2(item.Area.Center.X, item.Area.Center.Y), new Color(0, 0, 0, 64), 3); } foreach (GameObject item in gameWorld.GameObjects.Where(x => x.DrawPriority != DrawPriority.Invisible).OrderBy(x => x.DrawPriority)) { item.Draw(true); } foreach (var item in player.InteractableGameObjects) { item.EntityId.ToString().DrawStringOnScreen(new Vector2(30, 400)); } player.Rotation.ToString().DrawStringOnScreen(new Vector2(30, 30)); ($"MouseState: {mousePosition.X} {mousePosition.Y}").DrawStringOnScreen(new Vector2(130, 30)); ($"MouseState (world): {mouseWorldPosition.X} {mouseWorldPosition.Y}").DrawStringOnScreen(new Vector2(130, 70)); ($"Player collision realms: {string.Join(" ", player.CollisionRealms.Select(x => x.CollisionRealmId.ToString()).ToArray())}").DrawStringOnScreen(new Vector2(400, 30), new Color(0, 0, 0, 128)); ($"Box collision realms: {string.Join(" ", box.CollisionRealms.Select(x => x.CollisionRealmId.ToString()).ToArray())}").DrawStringOnScreen(new Vector2(400, 130), new Color(500, 0, 0, 128)); ($"Player blue ammo: {player.Inventory.AmmunitionInventoryBlue.Amount}").DrawStringOnScreen(new Vector2(400, 500), new Color(500, 0, 0, 128)); SpriteBatchExtensions.DrawHollowRectangleUnshifted(mousePosition, 3, 3, 3, Color.Red); SpriteBatchExtensions.DrawHollowRectangle(gameWorld.Area.Location, gameWorld.Area.Width, gameWorld.Area.Height, 5, Color.Black); spriteBatch.End(); base.Draw(gameTime); nextDraw = gameTime.TotalGameTime.TotalMilliseconds + GameConfig.Delta; } }
internal void DrawQuadTreeNode(ViewPortInfo viewPort, SpriteBatch spriteBatch, QuadTreeNode node, Rectangle destRectangle, SpriteFont spriteFont, float globalDispX, float globalDispY) { if (node == null) { return; } int actualX = (int)Math.Ceiling(node.pxBounds.X * viewPort.ActualZoom - globalDispX); int actualY = (int)Math.Ceiling(node.pxBounds.Y * viewPort.ActualZoom - globalDispY); // We need to calculate the 'Actual' width and height otherwise drawing might be innacurate when zoomed. int actualWidth = (int)Math.Ceiling(node.pxBounds.Width * viewPort.ActualZoom); int actualHeight = (int)Math.Ceiling(node.pxBounds.Height * viewPort.ActualZoom); // Only draw leaf nodes which are within the viewport specified. if (node.ChildNode1 == null && new Rectangle(actualX, actualY, actualWidth, actualHeight).Intersects(destRectangle)) { string nodeText = string.Format("{0}\n\r{1}", node.NodeID, node.Entities.Count); SpriteBatchExtensions.DrawRectangle(spriteBatch, new Rectangle(actualX, actualY, actualWidth, actualHeight), Color.Lime, 0); spriteBatch.DrawString( spriteFont, nodeText, new Vector2(actualX + actualWidth / 2.0f, actualY + actualHeight / 2.0f) - spriteFont.MeasureString(nodeText) / 2, Color.Lime ); } DrawQuadTreeNode(viewPort, spriteBatch, node.ChildNode1, destRectangle, spriteFont, globalDispX, globalDispY); DrawQuadTreeNode(viewPort, spriteBatch, node.ChildNode2, destRectangle, spriteFont, globalDispX, globalDispY); DrawQuadTreeNode(viewPort, spriteBatch, node.ChildNode3, destRectangle, spriteFont, globalDispX, globalDispY); DrawQuadTreeNode(viewPort, spriteBatch, node.ChildNode4, destRectangle, spriteFont, globalDispX, globalDispY); }
private static void Render(SpriteBatch spriteBatch, RenderTileMap renderTileMap) { for (var index = 0; index < renderTileMap.RenderTileLayers.Count; index++) { var renderTileLayer = renderTileMap.RenderTileLayers[index]; if (renderTileLayer.TileLayer.IsVisible) { for (var i = 0; i < renderTileLayer.RenderTiles.Count; i++) { var tile = renderTileLayer.RenderTiles[i]; SpriteBatchExtensions.Render(spriteBatch, (Sprite)tile.Sprite, (Vector2)tile.Position); } } } if (renderTileMap.Map.CollisionLayer.IsVisible) { foreach (var collisionTile in renderTileMap.Map.CollisionLayer) { spriteBatch.RenderFilledRectangle(collisionTile.Bounds, Color.Red * 0.3f); } } }
public ViewPortInfo DrawWorldViewPort(SpriteBatch spriteBatch, Vector2 center, float zoom, Rectangle destRectangle, Color color, SamplerState samplerState, SpriteFont spriteFont = null) { ViewPortInfo viewPortInfo = new ViewPortInfo(); { viewPortInfo.pxTileWidth = (int)Math.Ceiling(Map.TileWidth * zoom); viewPortInfo.pxTileHeight = (int)Math.Ceiling(Map.TileHeight * zoom); // Note about ActualZoom Property: // because there is a loss of data between to conversion from Map.pxTileWidth * Zoom -> (int) // we need to determine what was the actual level of zoom that was applied to the tiles and use that // this ensures that entities that will be drawn will be placed correctly on the screen. viewPortInfo.ActualZoom = viewPortInfo.pxTileWidth / Map.TileWidth; viewPortInfo.pxWidth = destRectangle.Width / viewPortInfo.ActualZoom; viewPortInfo.pxHeight = destRectangle.Height / viewPortInfo.ActualZoom; viewPortInfo.pxTopLeftX = center.X - viewPortInfo.pxWidth / 2.0f; viewPortInfo.pxTopLeftY = center.Y - viewPortInfo.pxHeight / 2.0f; viewPortInfo.TileCountX = (int)Math.Ceiling((double)viewPortInfo.pxWidth / Map.TileWidth) + 1; viewPortInfo.TileCountY = (int)Math.Ceiling((double)viewPortInfo.pxHeight / Map.TileHeight) + 1; // Prevent the View from going outisde of the WORLD coordinates. if (viewPortInfo.pxTopLeftX < 0) { viewPortInfo.pxTopLeftX = 0; } if (viewPortInfo.pxTopLeftY < 0) { viewPortInfo.pxTopLeftY = 0; } if (viewPortInfo.pxTopLeftX + viewPortInfo.pxWidth >= Map.pxWidth) { viewPortInfo.pxTopLeftX = Map.pxWidth - viewPortInfo.pxWidth; } if (viewPortInfo.pxTopLeftY + viewPortInfo.pxHeight >= Map.pxHeight) { viewPortInfo.pxTopLeftY = Map.pxHeight - viewPortInfo.pxHeight; } // Calculate any decimal displacement required (For Positions with decimal points). viewPortInfo.pxDispX = viewPortInfo.pxTopLeftX - ((int)viewPortInfo.pxTopLeftX / Map.TileWidth) * Map.TileWidth; viewPortInfo.pxDispY = viewPortInfo.pxTopLeftY - ((int)viewPortInfo.pxTopLeftY / Map.TileHeight) * Map.TileHeight; viewPortInfo.pxViewPortBounds = new Rectangle( (int)Math.Ceiling(viewPortInfo.pxTopLeftX), (int)Math.Ceiling(viewPortInfo.pxTopLeftY), (int)Math.Ceiling(viewPortInfo.pxWidth), (int)Math.Ceiling(viewPortInfo.pxHeight) ); } // RENDER THE GAME WORLD TO THE VIEWPORT RENDER TARGET GraphicsDevice.SetRenderTarget(_inputBuffer); GraphicsDevice.Clear(Map.Background); // DRAW THE WORLD MAP OverallPerformance.StartTiming("TileRenderingTime"); // Deferred Rendering should be fine for rendering tile as long as we draw tile layers one at a time spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, samplerState, null, null); { for (int layerIndex = 0; layerIndex < Map.TileLayers.Count; layerIndex++) { // DRAW EACH LAYER TileLayer tileLayer = Map.TileLayers[layerIndex]; if (tileLayer.Visible) { Color layerColor = new Color() { R = tileLayer.Color.R, G = tileLayer.Color.G, B = tileLayer.Color.B, A = (byte)(tileLayer.Color.A * tileLayer.Opacity) }; float depth = 1 - (layerIndex / 10000.0f); for (int i = 0; i < viewPortInfo.TileCountX; i++) { for (int j = 0; j < viewPortInfo.TileCountY; j++) { int tileX = (int)(i + viewPortInfo.pxTopLeftX / Map.TileWidth); int tileY = (int)(j + viewPortInfo.pxTopLeftY / Map.TileHeight); int tileGid = tileLayer[tileX, tileY]; Rectangle pxTileDestRect = new Rectangle( (int)Math.Ceiling(i * viewPortInfo.pxTileWidth - viewPortInfo.pxDispX * viewPortInfo.ActualZoom), (int)Math.Ceiling(j * viewPortInfo.pxTileHeight - viewPortInfo.pxDispY * viewPortInfo.ActualZoom), (int)viewPortInfo.pxTileWidth, (int)viewPortInfo.pxTileHeight ); if (tileGid != 0 && tileGid != -1) // NULL or INVALID Tile Gid is ignored { Tile tile = Map.Tiles[tileGid]; spriteBatch.Draw( tile.sourceTexture, pxTileDestRect, tile.SourceRectangle, layerColor, 0, Vector2.Zero, SpriteEffects.None, depth ); } // DRAW THE TILE LAYER GRID IF ENABLE if (DrawingOptions.ShowTileGrid && layerIndex == Map.TileLayers.Count - 1) { spriteBatch.DrawRectangle(pxTileDestRect, Color.Black, 0); } } } } } } spriteBatch.End(); OverallPerformance.StopTiming("TileRenderingTime"); // Calculate the entity Displacement caused by pxTopLeft at a global scale to prevent jittering. // Each entity should be displaced by the *same amount* based on the pxTopLeftX/Y values // this is to prevent entities 'jittering on the screen' when moving the camera. float globalDispX = (int)Math.Ceiling(viewPortInfo.pxTopLeftX * viewPortInfo.ActualZoom); float globalDispY = (int)Math.Ceiling(viewPortInfo.pxTopLeftY * viewPortInfo.ActualZoom); // DRAW VISIBLE REGISTERED ENTITIES OverallPerformance.RestartTiming("TotalEntityRenderTime"); spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend, samplerState, null, null); { EntitiesOnScreen = Collider.GetIntersectingEntites(new FRectangle(viewPortInfo.pxViewPortBounds)); // DRAW EACH ENTITIY THAT IS WITHIN THE SCREENS VIEWPORT foreach (Entity entity in EntitiesOnScreen) { EntityRenderPerformance.RestartTiming(entity.Name); if (!entity.Visible) { continue; } entity.IsOnScreen = true; // Determine the absolute position on the screen for entity position and the bounding box. Vector2 pxAbsEntityPos = new Vector2( entity.Pos.X * viewPortInfo.ActualZoom - globalDispX, entity.Pos.Y * viewPortInfo.ActualZoom - globalDispY ); FRectangle pxAbsBoundingBox = new FRectangle( entity.CurrentBoundingBox.X * viewPortInfo.ActualZoom - globalDispX, entity.CurrentBoundingBox.Y * viewPortInfo.ActualZoom - globalDispY, entity.CurrentBoundingBox.Width * viewPortInfo.ActualZoom, entity.CurrentBoundingBox.Height * viewPortInfo.ActualZoom ); // DRAW ENTITY BOUNDING BOXES IF ENABLED if (DrawingOptions.ShowBoundingBoxes) { spriteBatch.DrawRectangle(pxAbsBoundingBox.ToRectangle(), Color.Red, 0.0001f); SpriteBatchExtensions.DrawCross( spriteBatch, new Vector2( (int)Math.Ceiling(pxAbsEntityPos.X), (int)Math.Ceiling(pxAbsEntityPos.Y) ), 13, Color.Black, 0f); } // DRAW ENTITY DETAILS IF ENABLED (ENTITY DEBUG INFO) if (DrawingOptions.ShowEntityDebugInfo) { SpriteBatchExtensions.DrawMultiLineString( spriteBatch, spriteFont, entity.GetDebugInfo(), (int)entity.CurrentBoundingBox.Width * 2, 4, new Vector2( pxAbsBoundingBox.X + pxAbsBoundingBox.Width / 2, pxAbsBoundingBox.Y + pxAbsBoundingBox.Height / 2 ), Color.Purple); } // DRAW EVERY GAMEDRAWABLE INSTANCE CURRENTLY ACTIVE IN THE ENTITIES DRAWABLE SET. HashSet <GameDrawableInstance> drawableInstances = entity.Drawables.GetByState(entity.CurrentDrawableState); if (drawableInstances != null) { foreach (GameDrawableInstance drawable in drawableInstances) { if (!drawable.Visible) { continue; } // The relative position of the object should always be (X,Y) - (globalDispX, globalDispY). globalDispX and globalDispY // are based on viewPortInfo.TopLeftX and viewPortInfo.TopLeftY. viewPortInfo.TopLeftX and viewPortInfo.TopLeftY have // already been corrected in terms of the bounds of the WORLD map coordinates. This allows for panning at the edges. Rectangle pxCurrentFrame = drawable.GetSourceRectangle(LastUpdateTime); int pxObjectWidth = (int)Math.Ceiling(pxCurrentFrame.Width * entity.ScaleX * viewPortInfo.ActualZoom); int pxObjectHeight = (int)Math.Ceiling(pxCurrentFrame.Height * entity.ScaleY * viewPortInfo.ActualZoom); // Draw the Object based on the current Frame dimensions and the specified Object Width Height values. Rectangle objectDestRect = new Rectangle( (int)Math.Ceiling(pxAbsEntityPos.X) + (int)Math.Ceiling(drawable.Offset.X * viewPortInfo.ActualZoom), (int)Math.Ceiling(pxAbsEntityPos.Y) + (int)Math.Ceiling(drawable.Offset.Y * viewPortInfo.ActualZoom), pxObjectWidth, pxObjectHeight ); Vector2 drawableOrigin = new Vector2( (float)Math.Ceiling(drawable.Drawable.Origin.X * pxCurrentFrame.Width), (float)Math.Ceiling(drawable.Drawable.Origin.Y * pxCurrentFrame.Height) ); Color drawableColor = new Color() { R = drawable.Color.R, G = drawable.Color.G, B = drawable.Color.B, A = (byte)(drawable.Color.A * entity.Opacity) }; // Layer depth should depend how far down the object is on the map (Relative to Y). // Important to also take into account the animation layers for the entity. float layerDepth = Math.Min(0.99f, 1 / (entity.Pos.Y + ((float)drawable.Layer / Map.pxHeight))); // FINALLY ... DRAW spriteBatch.Draw( drawable.GetSourceTexture(LastUpdateTime), objectDestRect, pxCurrentFrame, drawableColor, drawable.Rotation, drawableOrigin, drawable.SpriteEffects, layerDepth); // DRAW BOUNDING BOXES OF EACH INDIVIDUAL DRAWABLE COMPONENT if (DrawingOptions.ShowDrawableComponents) { Rectangle drawableComponentRect = new Rectangle( (int)Math.Floor(objectDestRect.X - objectDestRect.Width * drawable.Drawable.Origin.X), (int)Math.Floor(objectDestRect.Y - objectDestRect.Height * drawable.Drawable.Origin.Y), objectDestRect.Width, objectDestRect.Height); SpriteBatchExtensions.DrawRectangle( spriteBatch, drawableComponentRect, Color.Blue, 0); } } } EntityRenderPerformance.StopTiming(entity.Name); } } spriteBatch.End(); OverallPerformance.StopTiming("TotalEntityRenderTime"); // APPLY GAME SHADERS TO THE RESULTANT IMAGE OverallPerformance.RestartTiming("TotalPostGameShaderRenderTime"); foreach (PostGameShader postGameShader in GameShaders) { if (postGameShader.Enabled) { postGameShader.ApplyShader(spriteBatch, viewPortInfo, LastUpdateTime, _inputBuffer, _outputBuffer); // Swap buffers after each render. _dummyBuffer = _inputBuffer; _inputBuffer = _outputBuffer; _outputBuffer = _dummyBuffer; } } OverallPerformance.StopTiming("TotalPostGameShaderRenderTime"); // DRAW COLLIDER DEBUG INFORMATION IF ENABLED if (DrawingOptions.ShowColliderDebugInfo) { spriteBatch.Begin(); Collider.DrawDebugInfo(viewPortInfo, spriteBatch, destRectangle, spriteFont, globalDispX, globalDispY); spriteBatch.End(); } // DRAW THE VIEWPORT TO THE STANDARD SCREEN GraphicsDevice.SetRenderTarget(null); spriteBatch.Begin(); { spriteBatch.Draw(_inputBuffer, destRectangle, color); } spriteBatch.End(); return(viewPortInfo); }
public override void Update() { var deltaSeconds = Stopwatch.Elapsed.TotalSeconds; InfoViewer.Log("Client FPS", Math.Round(1f / deltaSeconds, 2).ToString()); InfoViewer.Log("Roundtrip", _server?.Roundtrip.ToString()); InfoViewer.Log("Roundtrip Varience", _server?.RoundtripVarience.ToString()); Stopwatch.Restart(); NetworkEvent networkEvent = _client.Poll(); while (networkEvent.Type != NetworkEventType.Nothing) { switch (networkEvent.Type) { case NetworkEventType.Connect: _server = networkEvent.Connection; break; case NetworkEventType.Data: var diff = _messageTimer.Elapsed.TotalMilliseconds; //InfoViewer.Values["Message Time"] = Math.Round(diff, 4).ToString(); _messageTimer.Restart(); MessageRecieved(networkEvent.Data); break; } networkEvent.Recycle(); networkEvent = _client.Poll(); } _imGuiRenderer.Update((float)deltaSeconds, _window.InputSnapshot); var imGuiWantsMouse = ImGuiNET.ImGui.GetIO().WantCaptureMouse; var cameraEntities = _camerasSet.GetEntities(); var cameraTransform = cameraEntities.Length > 0 ? cameraEntities[0].Get<Transform>() : new Transform(); var inputTrackerTransform = Matrix3x2.CreateTranslation(-_window.Width / 2f, -_window.Height / 2f) * Matrix3x2.CreateScale(1 / Settings.GRAPHICS_SCALE, -1 / Settings.GRAPHICS_SCALE) * Matrix3x2.CreateScale(1 / _zoom) * cameraTransform.Matrix; _cameraSpaceInputTracker.SetTransform(inputTrackerTransform); _cameraSpaceGameInputTracker.SetActive(!imGuiWantsMouse); _zoom += _window.InputSnapshot.WheelDelta * 0.1f; PreUpdate(deltaSeconds); Scene.Update(new LogicUpdate((float)deltaSeconds, _cameraSpaceGameInputTracker)); PostUpdate(deltaSeconds); var serverMessages = new List<object>(); _editorMenu.Run(new EditorUpdate() { CameraSpaceInput = _cameraSpaceInputTracker, CameraSpaceGameInput = _cameraSpaceGameInputTracker, Scene = Scene, ServerMessages = serverMessages }); var clientUpdate = new ClientSystemUpdate() { Messages = serverMessages, Input = _cameraSpaceGameInputTracker }; foreach (var system in _clientSystems) { system.Update(clientUpdate); } if(_server != null) { var messages = SerializeMessages(serverMessages); _server.Send(messages, 5, true, _messagesSent++); } cameraEntities = _camerasSet.GetEntities(); cameraTransform = cameraEntities.Length > 0 ? cameraEntities[0].Get<Transform>() : new Transform(); var cameraMatrix = cameraTransform.GetCameraMatrix(Settings.GRAPHICS_SCALE) * Matrix4x4.CreateScale(_zoom); var vp = _viewport.Viewport; _drawDevice.Begin(cameraMatrix * _viewport.GetScalingTransform(), vp); Scene.Render(_drawDevice); float gridSize = 20; var gridCenter = new Vector2((int)Math.Round(cameraTransform.WorldPosition.X / gridSize) * gridSize, (int)Math.Round(cameraTransform.WorldPosition.Y / gridSize) * gridSize); for (int x = -2; x <= 2; x++) { for (int y = -2; y <= 2; y++) { SpriteBatchExtensions.DrawCircle(_drawDevice, (gridCenter + new Vector2(x, y) * gridSize) * Settings.GRAPHICS_SCALE, 0.2f * Settings.GRAPHICS_SCALE, 8, RgbaFloat.Red); } } _drawDevice.Draw(); _imGuiRenderer.Render(_drawDevice.GraphicsDevice, _drawDevice.CommandList); _drawDevice.End(); _window.GraphicsDevice.SwapBuffers(_window.MainSwapchain); _window.GraphicsDevice.WaitForIdle(); }