public List<Body> RightReleasedCallback() { List<Body> toReturn = new List<Body>(); toReturn.AddRange(SelectionBuffer); SelectionBuffer.Clear(); Selected.Invoke(toReturn, InputManager.MouseButton.Right); return toReturn; }
public List <VoxelHandle> RightReleasedCallback() { var toReturn = new List <VoxelHandle>(); toReturn.AddRange(SelectionBuffer); SelectionBuffer.Clear(); Selected.Invoke(toReturn, InputManager.MouseButton.Right); return(toReturn); }
/// <summary> /// Called whenever the left mouse button was released. /// </summary> /// <returns>A list of selected bodies.</returns> public List <Body> LeftReleasedCallback() { var toReturn = new List <Body>(); toReturn.AddRange(SelectionBuffer); SelectionBuffer.Clear(); Selected.Invoke(toReturn, InputManager.MouseButton.Left); return(toReturn); }
public List <Voxel> LeftReleasedCallback() { List <Voxel> toReturn = new List <Voxel>(); if (SelectionBuffer.Count > 0) { toReturn.AddRange(SelectionBuffer); SelectionBuffer.Clear(); Selected.Invoke(toReturn, InputManager.MouseButton.Left); } return(toReturn); }
private void HandleMouseButton(ButtonState ButtonState, VoxelHandle underMouse, bool newVoxel, bool altPressed, ref bool ButtonPressed, InputManager.MouseButton Button) { // If the left mouse button is pressed, update the slection buffer. if (ButtonPressed) { // On release, select voxels. if (ButtonState == ButtonState.Released) { ReleaseSound.Play(World.Renderer.CursorLightPos); ButtonPressed = false; if (SelectionBuffer.Count > 0) { var t = new List <VoxelHandle>(SelectionBuffer); SelectionBuffer.Clear(); Selected.Invoke(t, Button); } BoxYOffset = 0; PrevBoxYOffsetInt = 0; } // Otherwise, update the selection buffer else { if (SelectionBuffer.Count == 0) { FirstVoxel = underMouse; SelectionBuffer.Add(underMouse); } else { SelectionBuffer.Clear(); SelectionBuffer.Add(FirstVoxel); SelectionBuffer.Add(underMouse); BoundingBox buffer = GetSelectionBox(); // Update the selection box to account for offsets from mouse wheel. if (BoxYOffset > 0) { buffer.Max.Y = MathFunctions.Clamp(buffer.Max.Y + (int)BoxYOffset, 0, World.WorldSizeInVoxels.Y - 1); } else if (BoxYOffset < 0) { buffer.Min.Y = MathFunctions.Clamp(buffer.Min.Y - (int)BoxYOffset, 0, World.WorldSizeInVoxels.Y - 1); } SelectionBuffer = Select(buffer, FirstVoxel.WorldPosition, underMouse.WorldPosition).ToList(); if (!altPressed && Brush.CullUnseenVoxels && SelectionType == VoxelSelectionType.SelectFilled) { SelectionBuffer.RemoveAll(v => { if (v.Equals(underMouse)) { return(false); } if (World.PersistentData.Designations.IsVoxelDesignation(v, DesignationType.Put)) { return(false); // Treat put designations as solid. } return(!VoxelHelpers.DoesVoxelHaveVisibleSurface(World, v)); }); } if (newVoxel) { DragSound.Play(World.Renderer.CursorLightPos, SelectionBuffer.Count / 20.0f); Dragged.Invoke(SelectionBuffer, Button); } } } } // If the mouse was not previously pressed, but is now pressed, then notify us of that. else if (ButtonState == ButtonState.Pressed) { ClickSound.Play(World.Renderer.CursorLightPos);; ButtonPressed = true; BoxYOffset = 0; PrevBoxYOffsetInt = 0; } }
public void Clear() { SelectionBuffer.Clear(); }
public Voxel RightPressedCallback() { SelectionBuffer.Clear(); return(GetVoxelUnderMouse()); }
public void Update() { MouseState mouse = Mouse.GetState(); KeyboardState keyboard = Keyboard.GetState(); Voxel underMouse = GetVoxelUnderMouse(); bool newVoxel = underMouse != null && !underMouse.Equals(VoxelUnderMouse); if (underMouse != null) { VoxelUnderMouse = underMouse; PlayState.CursorLightPos = underMouse.Position + new Vector3(0.5f, 0.5f, 0.5f); if (Enabled && underMouse.TypeName != "empty" && underMouse.IsExplored) { string info = underMouse.TypeName; if (PlayState.PlayerFaction.RoomBuilder.IsInRoom(underMouse)) { Room room = PlayState.PlayerFaction.RoomBuilder.GetMostLikelyRoom(underMouse); if (room != null) { info += " (" + room.ID + ")"; } } PlayState.GUI.ToolTipManager.PopupInfo(info); } } if (!Enabled) { return; } if (keyboard.IsKeyDown(Keys.LeftAlt) || keyboard.IsKeyDown(Keys.RightAlt)) { BoxYOffset += (float)(mouse.ScrollWheelValue - LastMouseWheel) * 0.01f; LastMouseWheel = mouse.ScrollWheelValue; newVoxel = true; } else { LastMouseWheel = mouse.ScrollWheelValue; } if (underMouse != null) { BoundingBox box = underMouse.GetBoundingBox().Expand(0.05f); Drawer3D.DrawBox(box, CurrentColor, CurrentWidth, true); } if (isLeftPressed) { if (mouse.LeftButton == ButtonState.Released) { isLeftPressed = false; LeftReleasedCallback(); BoxYOffset = 0; } else { if (SelectionBuffer.Count == 0) { FirstVoxel = underMouse; SelectionBuffer.Add(underMouse); } else { SelectionBuffer.Clear(); SelectionBuffer.Add(FirstVoxel); SelectionBuffer.Add(underMouse); BoundingBox buffer = GetSelectionBox(); if (BoxYOffset > 0) { buffer.Max.Y += BoxYOffset; } else if (BoxYOffset < 0) { buffer.Min.Y += BoxYOffset; } SelectionBuffer = Chunks.GetVoxelsIntersecting(buffer); if (newVoxel) { Dragged.Invoke(SelectionBuffer, InputManager.MouseButton.Left); } } } } else if (mouse.LeftButton == ButtonState.Pressed) { LeftPressedCallback(); isLeftPressed = true; BoxYOffset = 0; } if (isRightPressed) { if (mouse.RightButton == ButtonState.Released) { isRightPressed = false; RightReleasedCallback(); BoxYOffset = 0; } else { if (SelectionBuffer.Count == 0) { SelectionBuffer.Add(underMouse); FirstVoxel = underMouse; } else { SelectionBuffer.Clear(); SelectionBuffer.Add(FirstVoxel); SelectionBuffer.Add(underMouse); BoundingBox buffer = GetSelectionBox(); if (BoxYOffset > 0) { buffer.Max.Y += BoxYOffset; } else if (BoxYOffset < 0) { buffer.Min.Y += BoxYOffset; } SelectionBuffer = Chunks.GetVoxelsIntersecting(buffer); if (newVoxel) { Dragged.Invoke(SelectionBuffer, InputManager.MouseButton.Right); } } } } else if (mouse.RightButton == ButtonState.Pressed) { RightPressedCallback(); BoxYOffset = 0; isRightPressed = true; } }
/// <summary> /// Called when a frame is to be drawn to the screen /// </summary> /// <param name="gameTime">The current time</param> public void Render(DwarfTime gameTime) { if (!World.ShowingWorld) { return; } ValidateShader(); var frustum = Camera.GetDrawFrustum(); var renderables = World.EnumerateIntersectingObjects(frustum, r => r.IsVisible && !World.ChunkManager.IsAboveCullPlane(r.GetBoundingBox())); // Controls the sky fog float x = (1.0f - Sky.TimeOfDay); x = x * x; DefaultShader.FogColor = new Color(0.32f * x, 0.58f * x, 0.9f * x); DefaultShader.LightPositions = LightPositions; CompositeLibrary.Render(GraphicsDevice); CompositeLibrary.Update(); GraphicsDevice.DepthStencilState = DepthStencilState.Default; GraphicsDevice.BlendState = BlendState.Opaque; if (lastWaterHeight < 0) // Todo: Seriously, every single frame?? { lastWaterHeight = 0; foreach (var chunk in World.ChunkManager.ChunkMap) { for (int y = 0; y < VoxelConstants.ChunkSizeY; y++) { if (chunk.Data.LiquidPresent[y] > 0) { lastWaterHeight = Math.Max(y + chunk.Origin.Y, lastWaterHeight); } } } } // Computes the water height. float wHeight = WaterRenderer.GetVisibleWaterHeight(World.ChunkManager, Camera, GraphicsDevice.Viewport, lastWaterHeight); lastWaterHeight = wHeight; // Draw reflection/refraction images WaterRenderer.DrawReflectionMap(renderables, gameTime, World, wHeight - 0.1f, GetReflectedCameraMatrix(wHeight), DefaultShader, GraphicsDevice); #region Draw Selection Buffer. if (SelectionBuffer == null) { SelectionBuffer = new SelectionBuffer(8, GraphicsDevice); } GraphicsDevice.RasterizerState = RasterizerState.CullNone; GraphicsDevice.DepthStencilState = DepthStencilState.Default; GraphicsDevice.BlendState = BlendState.Opaque; // Defines the current slice for the GPU var level = PersistentSettings.MaxViewingLevel >= World.WorldSizeInVoxels.Y ? 1000.0f : PersistentSettings.MaxViewingLevel + 0.25f; Plane slicePlane = WaterRenderer.CreatePlane(level, new Vector3(0, -1, 0), Camera.ViewMatrix, false); if (SelectionBuffer.Begin(GraphicsDevice)) { // Draw the whole world, and make sure to handle slicing DefaultShader.ClipPlane = new Vector4(slicePlane.Normal, slicePlane.D); DefaultShader.ClippingEnabled = true; DefaultShader.View = Camera.ViewMatrix; DefaultShader.Projection = Camera.ProjectionMatrix; DefaultShader.World = Matrix.Identity; //GamePerformance.Instance.StartTrackPerformance("Render - Selection Buffer - Chunks"); ChunkRenderer.RenderSelectionBuffer(DefaultShader, GraphicsDevice, Camera.ViewMatrix); //GamePerformance.Instance.StopTrackPerformance("Render - Selection Buffer - Chunks"); //GamePerformance.Instance.StartTrackPerformance("Render - Selection Buffer - Components"); ComponentRenderer.RenderSelectionBuffer(renderables, gameTime, World.ChunkManager, Camera, DwarfGame.SpriteBatch, GraphicsDevice, DefaultShader); //GamePerformance.Instance.StopTrackPerformance("Render - Selection Buffer - Components"); //GamePerformance.Instance.StartTrackPerformance("Render - Selection Buffer - Instances"); InstanceRenderer.Flush(GraphicsDevice, DefaultShader, Camera, InstanceRenderMode.SelectionBuffer); //GamePerformance.Instance.StopTrackPerformance("Render - Selection Buffer - Instances"); SelectionBuffer.End(GraphicsDevice); } #endregion // Start drawing the bloom effect if (GameSettings.Default.EnableGlow) { bloom.BeginDraw(); } // Draw the sky GraphicsDevice.Clear(DefaultShader.FogColor); DrawSky(gameTime, Camera.ViewMatrix, 1.0f, DefaultShader.FogColor); DefaultShader.FogEnd = GameSettings.Default.ChunkDrawDistance; DefaultShader.FogStart = GameSettings.Default.ChunkDrawDistance * 0.8f; CaveView = CaveView * 0.9f + TargetCaveView * 0.1f; DefaultShader.WindDirection = World.Weather.CurrentWind; DefaultShader.WindForce = 0.0005f * (1.0f + (float)Math.Sin(World.Time.GetTotalSeconds() * 0.001f)); // Draw the whole world, and make sure to handle slicing DefaultShader.ClipPlane = new Vector4(slicePlane.Normal, slicePlane.D); DefaultShader.ClippingEnabled = true; //Blue ghost effect above the current slice. DefaultShader.GhostClippingEnabled = true; Draw3DThings(gameTime, DefaultShader, Camera.ViewMatrix); // Now we want to draw the water on top of everything else DefaultShader.ClippingEnabled = true; DefaultShader.GhostClippingEnabled = false; //ComponentManager.CollisionManager.DebugDraw(); DefaultShader.View = Camera.ViewMatrix; DefaultShader.Projection = Camera.ProjectionMatrix; DefaultShader.GhostClippingEnabled = true; // Now draw all of the entities in the game DefaultShader.ClipPlane = new Vector4(slicePlane.Normal, slicePlane.D); DefaultShader.ClippingEnabled = true; // Render simple geometry (boxes, etc.) Drawer3D.Render(GraphicsDevice, DefaultShader, Camera, World.PersistentData.Designations, World); DefaultShader.EnableShadows = false; DefaultShader.View = Camera.ViewMatrix; ComponentRenderer.Render(renderables, gameTime, World.ChunkManager, Camera, DwarfGame.SpriteBatch, GraphicsDevice, DefaultShader, ComponentRenderer.WaterRenderType.None, lastWaterHeight); InstanceRenderer.Flush(GraphicsDevice, DefaultShader, Camera, InstanceRenderMode.Normal); if (World.UserInterface.CurrentToolMode == "BuildZone" || // Todo: ?? World.UserInterface.CurrentToolMode == "BuildWall" || World.UserInterface.CurrentToolMode == "BuildObject") { DefaultShader.View = Camera.ViewMatrix; DefaultShader.Projection = Camera.ProjectionMatrix; DefaultShader.SetTexturedTechnique(); GraphicsDevice.BlendState = BlendState.NonPremultiplied; } WaterRenderer.DrawWater( GraphicsDevice, (float)gameTime.TotalGameTime.TotalSeconds, DefaultShader, Camera.ViewMatrix, GetReflectedCameraMatrix(wHeight), Camera.ProjectionMatrix, new Vector3(0.1f, 0.0f, 0.1f), Camera, World.ChunkManager); World.ParticleManager.Render(World, GraphicsDevice); DefaultShader.ClippingEnabled = false; if (UseFXAA && fxaa == null) { fxaa = new FXAA(); fxaa.Initialize(); } if (GameSettings.Default.EnableGlow) { if (UseFXAA) { fxaa.Begin(DwarfTime.LastTime); } bloom.DrawTarget = UseFXAA ? fxaa.RenderTarget : null; bloom.Draw(gameTime.ToRealTime()); if (UseFXAA) { fxaa.End(DwarfTime.LastTime); } } else if (UseFXAA) { fxaa.End(DwarfTime.LastTime); } RasterizerState rasterizerState = new RasterizerState() { ScissorTestEnable = true }; if (Debugger.Switches.DrawSelectionBuffer) { SelectionBuffer.DebugDraw(GraphicsDevice.Viewport.Bounds); } try { DwarfGame.SafeSpriteBatchBegin(SpriteSortMode.Deferred, BlendState.NonPremultiplied, Drawer2D.PointMagLinearMin, null, rasterizerState, null, Matrix.Identity); //DwarfGame.SpriteBatch.Draw(Shadows.ShadowTexture, Vector2.Zero, Color.White); if (IsCameraUnderwater()) { Drawer2D.FillRect(DwarfGame.SpriteBatch, GraphicsDevice.Viewport.Bounds, new Color(10, 40, 60, 200)); } Drawer2D.Render(DwarfGame.SpriteBatch, Camera, GraphicsDevice.Viewport); IndicatorManager.Render(gameTime); } finally { try { DwarfGame.SpriteBatch.End(); } catch (Exception exception) { DwarfGame.SpriteBatch = new SpriteBatch(GraphicsDevice); } } if (Debugger.Switches.DrawComposites) { Vector2 offset = Vector2.Zero; foreach (var composite in CompositeLibrary.Composites) { offset = composite.Value.DebugDraw(DwarfGame.SpriteBatch, (int)offset.X, (int)offset.Y); } } DwarfGame.SpriteBatch.GraphicsDevice.ScissorRectangle = DwarfGame.SpriteBatch.GraphicsDevice.Viewport.Bounds; GraphicsDevice.DepthStencilState = DepthStencilState.Default; GraphicsDevice.BlendState = BlendState.Opaque; foreach (var module in World.UpdateSystems) { module.Render(gameTime, World.ChunkManager, Camera, DwarfGame.SpriteBatch, GraphicsDevice, DefaultShader); } lock (ScreenshotLock) { foreach (Screenshot shot in Screenshots) { TakeScreenshot(shot.FileName, shot.Resolution); } Screenshots.Clear(); } }
public void Update() { MouseState mouse = Mouse.GetState(); KeyboardState keyboard = Keyboard.GetState(); var underMouse = GetVoxelUnderMouse(); // Keep track of whether a new voxel has been selected. bool newVoxel = underMouse.IsValid && underMouse != VoxelUnderMouse; if (!underMouse.IsValid) { return; } VoxelUnderMouse = underMouse; // Update the cursor light. World.CursorLightPos = underMouse.WorldPosition + new Vector3(0.5f, 0.5f, 0.5f); // Get the type of the voxel and display it to the player. if (Enabled && !underMouse.IsEmpty && underMouse.IsExplored) { string info = underMouse.Type.Name; // If it belongs to a room, display that information. if (World.PlayerFaction.RoomBuilder.IsInRoom(underMouse)) { Room room = World.PlayerFaction.RoomBuilder.GetMostLikelyRoom(underMouse); if (room != null) { info += " (" + room.ID + ")"; } } World.ShowInfo(info); } // Do nothing if not enabled. if (!Enabled) { return; } bool altPressed = false; // If the left or right ALT keys are pressed, we can adjust the height of the selection // for building pits and tall walls using the mouse wheel. if (keyboard.IsKeyDown(Keys.LeftAlt) || keyboard.IsKeyDown(Keys.RightAlt)) { var change = mouse.ScrollWheelValue - LastMouseWheel; BoxYOffset += (change) * 0.01f; int offset = (int)BoxYOffset; if (offset != PrevBoxYOffsetInt) { DragSound.Play(World.CursorLightPos); newVoxel = true; } PrevBoxYOffsetInt = offset; altPressed = true; } else { PrevBoxYOffsetInt = 0; } LastMouseWheel = mouse.ScrollWheelValue; // Draw a box around the current voxel under the mouse. if (underMouse.IsValid) { BoundingBox box = underMouse.GetBoundingBox().Expand(0.05f); Drawer3D.DrawBox(box, CurrentColor, CurrentWidth, true); } // If the left mouse button is pressed, update the slection buffer. if (isLeftPressed) { // On release, select voxels. if (mouse.LeftButton == ButtonState.Released) { ReleaseSound.Play(World.CursorLightPos); isLeftPressed = false; LeftReleasedCallback(); BoxYOffset = 0; PrevBoxYOffsetInt = 0; } // Otherwise, update the selection buffer else { if (SelectionBuffer.Count == 0) { FirstVoxel = underMouse; SelectionBuffer.Add(underMouse); } else { SelectionBuffer.Clear(); SelectionBuffer.Add(FirstVoxel); SelectionBuffer.Add(underMouse); BoundingBox buffer = GetSelectionBox(); // Update the selection box to account for offsets from mouse wheel. if (BoxYOffset > 0) { buffer.Max.Y += (int)BoxYOffset; } else if (BoxYOffset < 0) { buffer.Min.Y += (int)BoxYOffset; } SelectionBuffer = Select(buffer, FirstVoxel.WorldPosition, underMouse.WorldPosition).ToList(); if (!altPressed && Brush != VoxelBrush.Stairs) { if (SelectionType == VoxelSelectionType.SelectFilled) { SelectionBuffer.RemoveAll(v => { if (v.Equals(underMouse)) { return(false); } return(v.IsExplored && !VoxelHelpers.DoesVoxelHaveVisibleSurface( Chunks.ChunkData, v)); }); } } if (newVoxel) { DragSound.Play(World.CursorLightPos, SelectionBuffer.Count / 20.0f); Dragged.Invoke(SelectionBuffer, InputManager.MouseButton.Left); } } } } // If the mouse was not previously pressed, but is now pressed, then notify us of that. else if (mouse.LeftButton == ButtonState.Pressed) { ClickSound.Play(World.CursorLightPos);; isLeftPressed = true; BoxYOffset = 0; PrevBoxYOffsetInt = 0; } // Case where the right mouse button is pressed (mirrors left mouse button) // TODO(Break this into a function) if (isRightPressed) { if (mouse.RightButton == ButtonState.Released) { ReleaseSound.Play(World.CursorLightPos); isRightPressed = false; RightReleasedCallback(); BoxYOffset = 0; PrevBoxYOffsetInt = 0; } else { if (SelectionBuffer.Count == 0) { SelectionBuffer.Add(underMouse); FirstVoxel = underMouse; } else { SelectionBuffer.Clear(); SelectionBuffer.Add(FirstVoxel); SelectionBuffer.Add(underMouse); BoundingBox buffer = GetSelectionBox(); if (BoxYOffset > 0) { buffer.Max.Y += (int)BoxYOffset; } else if (BoxYOffset < 0) { buffer.Min.Y += (int)BoxYOffset; } SelectionBuffer = VoxelHelpers.EnumerateCoordinatesInBoundingBox(buffer) .Select(c => new VoxelHandle(Chunks.ChunkData, c)) .Where(v => v.IsValid) .ToList(); if (newVoxel) { DragSound.Play(World.CursorLightPos, SelectionBuffer.Count / 20.0f); Dragged.Invoke(SelectionBuffer, InputManager.MouseButton.Right); } } } } else if (mouse.RightButton == ButtonState.Pressed) { ClickSound.Play(World.CursorLightPos); RightPressedCallback(); BoxYOffset = 0; isRightPressed = true; } }
public void Update() { MouseState mouse = Mouse.GetState(); KeyboardState keyboard = Keyboard.GetState(); Voxel underMouse = GetVoxelUnderMouse(); // Keep track of whether a new voxel has been selected. bool newVoxel = underMouse != null && !underMouse.Equals(VoxelUnderMouse); // If there is a voxel under the mouse... if (underMouse != null) { VoxelUnderMouse = underMouse; // Update the cursor light. PlayState.CursorLightPos = underMouse.Position + new Vector3(0.5f, 0.5f, 0.5f); // Get the type of the voxel and display it to the player. if (Enabled && !underMouse.IsEmpty && underMouse.IsExplored) { string info = underMouse.TypeName; // If it belongs to a room, display that information. if (PlayState.PlayerFaction.RoomBuilder.IsInRoom(underMouse)) { Room room = PlayState.PlayerFaction.RoomBuilder.GetMostLikelyRoom(underMouse); if (room != null) { info += " (" + room.ID + ")"; } } PlayState.GUI.ToolTipManager.PopupInfo(info); } } // Do nothing if not enabled. if (!Enabled) { return; } bool altPressed = false; // If the left or right ALT keys are pressed, we can adjust the height of the selection // for building pits and tall walls using the mouse wheel. if (keyboard.IsKeyDown(Keys.LeftAlt) || keyboard.IsKeyDown(Keys.RightAlt)) { BoxYOffset += (mouse.ScrollWheelValue - LastMouseWheel) * 0.01f; LastMouseWheel = mouse.ScrollWheelValue; newVoxel = true; altPressed = true; } else { LastMouseWheel = mouse.ScrollWheelValue; } // Draw a box around the current voxel under the mouse. if (underMouse != null) { BoundingBox box = underMouse.GetBoundingBox().Expand(0.05f); Drawer3D.DrawBox(box, CurrentColor, CurrentWidth, true); } // If the left mouse button is pressed, update the slection buffer. if (isLeftPressed) { // On release, select voxels. if (mouse.LeftButton == ButtonState.Released) { isLeftPressed = false; LeftReleasedCallback(); BoxYOffset = 0; } // Otherwise, update the selection buffer else { if (SelectionBuffer.Count == 0) { FirstVoxel = underMouse; SelectionBuffer.Add(underMouse); } else { SelectionBuffer.Clear(); SelectionBuffer.Add(FirstVoxel); SelectionBuffer.Add(underMouse); BoundingBox buffer = GetSelectionBox(); // Update the selection box to account for offsets from mouse wheel. if (BoxYOffset > 0) { buffer.Max.Y += BoxYOffset; } else if (BoxYOffset < 0) { buffer.Min.Y += BoxYOffset; } SelectionBuffer = Chunks.GetVoxelsIntersecting(buffer); if (!altPressed) { SelectionBuffer.RemoveAll( voxel => (!voxel.Equals(underMouse) && Chunks.ChunkData.IsVoxelOccluded(voxel))); } if (newVoxel) { Dragged.Invoke(SelectionBuffer, InputManager.MouseButton.Left); } } } } // If the mouse was not previously pressed, but is now pressed, then notify us of that. else if (mouse.LeftButton == ButtonState.Pressed) { LeftPressedCallback(); isLeftPressed = true; BoxYOffset = 0; } // Case where the right mouse button is pressed (mirrors left mouse button) // TODO(Break this into a function) if (isRightPressed) { if (mouse.RightButton == ButtonState.Released) { isRightPressed = false; RightReleasedCallback(); BoxYOffset = 0; } else { if (SelectionBuffer.Count == 0) { SelectionBuffer.Add(underMouse); FirstVoxel = underMouse; } else { SelectionBuffer.Clear(); SelectionBuffer.Add(FirstVoxel); SelectionBuffer.Add(underMouse); BoundingBox buffer = GetSelectionBox(); if (BoxYOffset > 0) { buffer.Max.Y += BoxYOffset; } else if (BoxYOffset < 0) { buffer.Min.Y += BoxYOffset; } SelectionBuffer = Chunks.GetVoxelsIntersecting(buffer); if (!altPressed) { SelectionBuffer.RemoveAll( voxel => (!voxel.Equals(underMouse) && Chunks.ChunkData.IsVoxelOccluded(voxel))); } if (newVoxel) { Dragged.Invoke(SelectionBuffer, InputManager.MouseButton.Right); } } } } else if (mouse.RightButton == ButtonState.Pressed) { RightPressedCallback(); BoxYOffset = 0; isRightPressed = true; } }
/// <summary> /// Called when a frame is to be drawn to the screen /// </summary> /// <param name="gameTime">The current time</param> public void Render(DwarfTime gameTime) { if (!ShowingWorld) { return; } #if RENDER_VOXEL_ICONS var voxels = VoxelLibrary.RenderIcons(GraphicsDevice, DefaultShader, ChunkManager, -1, -1, 32); using (var stream = new FileStream("voxels.png", FileMode.OpenOrCreate)) { GraphicsDevice.SetRenderTarget(null); voxels.SaveAsPng(stream, voxels.Width, voxels.Height); } #endif GamePerformance.Instance.StartTrackPerformance("Render - RENDER"); GamePerformance.Instance.StartTrackPerformance("Render - Prep"); var renderables = ComponentRenderer.EnumerateVisibleRenderables(ComponentManager.GetRenderables(), ChunkManager, Camera); // Controls the sky fog float x = (1.0f - Sky.TimeOfDay); x = x * x; DefaultShader.FogColor = new Color(0.32f * x, 0.58f * x, 0.9f * x); DefaultShader.LightPositions = LightPositions; CompositeLibrary.Render(GraphicsDevice); CompositeLibrary.Update(); GraphicsDevice.DepthStencilState = DepthStencilState.Default; GraphicsDevice.BlendState = BlendState.Opaque; if (GameSettings.Default.UseDynamicShadows) { ChunkRenderer.RenderShadowmap(DefaultShader, GraphicsDevice, Shadows, Matrix.Identity, Tilesheet); } if (GameSettings.Default.UseLightmaps) { ChunkRenderer.RenderLightmaps(Camera, gameTime, GraphicsDevice, DefaultShader, Matrix.Identity); } // Computes the water height. float wHeight = WaterRenderer.GetVisibleWaterHeight(ChunkManager, Camera, GraphicsDevice.Viewport, lastWaterHeight); lastWaterHeight = wHeight; // Draw reflection/refraction images WaterRenderer.DrawReflectionMap(renderables, gameTime, this, wHeight - 0.1f, GetReflectedCameraMatrix(wHeight), DefaultShader, GraphicsDevice); GamePerformance.Instance.StopTrackPerformance("Render - Prep"); GamePerformance.Instance.StartTrackPerformance("Render - Selection Buffer"); #region Draw Selection Buffer. if (SelectionBuffer == null) { SelectionBuffer = new SelectionBuffer(8, GraphicsDevice); } GraphicsDevice.RasterizerState = RasterizerState.CullNone; GraphicsDevice.DepthStencilState = DepthStencilState.Default; GraphicsDevice.BlendState = BlendState.Opaque; Plane slicePlane = WaterRenderer.CreatePlane(SlicePlane, new Vector3(0, -1, 0), Camera.ViewMatrix, false); if (SelectionBuffer.Begin(GraphicsDevice)) { // Draw the whole world, and make sure to handle slicing DefaultShader.ClipPlane = new Vector4(slicePlane.Normal, slicePlane.D); DefaultShader.ClippingEnabled = true; DefaultShader.View = Camera.ViewMatrix; DefaultShader.Projection = Camera.ProjectionMatrix; DefaultShader.World = Matrix.Identity; //GamePerformance.Instance.StartTrackPerformance("Render - Selection Buffer - Chunks"); ChunkRenderer.RenderSelectionBuffer(DefaultShader, GraphicsDevice, Camera.ViewMatrix); //GamePerformance.Instance.StopTrackPerformance("Render - Selection Buffer - Chunks"); //GamePerformance.Instance.StartTrackPerformance("Render - Selection Buffer - Components"); ComponentRenderer.RenderSelectionBuffer(renderables, gameTime, ChunkManager, Camera, DwarfGame.SpriteBatch, GraphicsDevice, DefaultShader); //GamePerformance.Instance.StopTrackPerformance("Render - Selection Buffer - Components"); //GamePerformance.Instance.StartTrackPerformance("Render - Selection Buffer - Instances"); NewInstanceManager.RenderInstances(GraphicsDevice, DefaultShader, Camera, InstanceRenderer.RenderMode.SelectionBuffer); //GamePerformance.Instance.StopTrackPerformance("Render - Selection Buffer - Instances"); SelectionBuffer.End(GraphicsDevice); GamePerformance.Instance.TrackValueType("SBUFFER RENDERED", true); } else { GamePerformance.Instance.TrackValueType("SBUFFER RENDERED", false); } #endregion GamePerformance.Instance.StopTrackPerformance("Render - Selection Buffer"); GamePerformance.Instance.StartTrackPerformance("Render - BG Stuff"); // Start drawing the bloom effect if (GameSettings.Default.EnableGlow) { bloom.BeginDraw(); } // Draw the sky GraphicsDevice.Clear(DefaultShader.FogColor); DrawSky(gameTime, Camera.ViewMatrix, 1.0f, DefaultShader.FogColor); // Defines the current slice for the GPU float level = ChunkManager.ChunkData.MaxViewingLevel + 0.25f; if (level > VoxelConstants.ChunkSizeY) { level = 1000; } GamePerformance.Instance.StopTrackPerformance("Render - BG Stuff"); GamePerformance.Instance.StartTrackPerformance("Render - Chunks"); SlicePlane = level; DefaultShader.WindDirection = Weather.CurrentWind; DefaultShader.WindForce = 0.0005f * (1.0f + (float)Math.Sin(Time.GetTotalSeconds() * 0.001f)); // Draw the whole world, and make sure to handle slicing DefaultShader.ClipPlane = new Vector4(slicePlane.Normal, slicePlane.D); DefaultShader.ClippingEnabled = true; //Blue ghost effect above the current slice. DefaultShader.GhostClippingEnabled = true; Draw3DThings(gameTime, DefaultShader, Camera.ViewMatrix); GamePerformance.Instance.StopTrackPerformance("Render - Chunks"); // Now we want to draw the water on top of everything else DefaultShader.ClippingEnabled = true; DefaultShader.GhostClippingEnabled = false; //ComponentManager.CollisionManager.DebugDraw(); DefaultShader.View = Camera.ViewMatrix; DefaultShader.Projection = Camera.ProjectionMatrix; DefaultShader.GhostClippingEnabled = true; // Now draw all of the entities in the game DefaultShader.ClipPlane = new Vector4(slicePlane.Normal, slicePlane.D); DefaultShader.ClippingEnabled = true; GamePerformance.Instance.StartTrackPerformance("Render - Drawer3D"); // Render simple geometry (boxes, etc.) Drawer3D.Render(GraphicsDevice, DefaultShader, Camera, DesignationDrawer, PlayerFaction.Designations, this); GamePerformance.Instance.StopTrackPerformance("Render - Drawer3D"); GamePerformance.Instance.StartTrackPerformance("Render - Instances"); DefaultShader.EnableShadows = GameSettings.Default.UseDynamicShadows; if (GameSettings.Default.UseDynamicShadows) { Shadows.BindShadowmapEffect(DefaultShader); } DefaultShader.View = Camera.ViewMatrix; NewInstanceManager.RenderInstances(GraphicsDevice, DefaultShader, Camera, InstanceRenderer.RenderMode.Normal); GamePerformance.Instance.StopTrackPerformance("Render - Instances"); GamePerformance.Instance.StartTrackPerformance("Render - Components"); ComponentRenderer.Render(renderables, gameTime, ChunkManager, Camera, DwarfGame.SpriteBatch, GraphicsDevice, DefaultShader, ComponentRenderer.WaterRenderType.None, lastWaterHeight); GamePerformance.Instance.StopTrackPerformance("Render - Components"); GamePerformance.Instance.StartTrackPerformance("Render - Tools"); if (Master.CurrentToolMode == GameMaster.ToolMode.BuildZone || Master.CurrentToolMode == GameMaster.ToolMode.BuildWall || Master.CurrentToolMode == GameMaster.ToolMode.BuildObject) { DefaultShader.View = Camera.ViewMatrix; DefaultShader.Projection = Camera.ProjectionMatrix; DefaultShader.SetTexturedTechnique(); GraphicsDevice.BlendState = BlendState.NonPremultiplied; Master.Faction.CraftBuilder.Render(gameTime, GraphicsDevice, DefaultShader); } GamePerformance.Instance.StopTrackPerformance("Render - Tools"); GamePerformance.Instance.StartTrackPerformance("Render - Water"); WaterRenderer.DrawWater( GraphicsDevice, (float)gameTime.TotalGameTime.TotalSeconds, DefaultShader, Camera.ViewMatrix, GetReflectedCameraMatrix(wHeight), Camera.ProjectionMatrix, new Vector3(0.1f, 0.0f, 0.1f), Camera, ChunkManager); GamePerformance.Instance.StopTrackPerformance("Render - Water"); GamePerformance.Instance.StartTrackPerformance("Render - Misc"); DefaultShader.ClippingEnabled = false; if (GameSettings.Default.EnableGlow) { bloom.DrawTarget = UseFXAA ? fxaa.RenderTarget : null; if (UseFXAA) { fxaa.Begin(DwarfTime.LastTime, fxaa.RenderTarget); } bloom.Draw(gameTime.ToGameTime()); if (UseFXAA) { fxaa.End(DwarfTime.LastTime, fxaa.RenderTarget); } } else if (UseFXAA) { fxaa.End(DwarfTime.LastTime, fxaa.RenderTarget); } RasterizerState rasterizerState = new RasterizerState() { ScissorTestEnable = true }; //if (CompositeLibrary.Composites.ContainsKey("resources")) // CompositeLibrary.Composites["resources"].DebugDraw(DwarfGame.SpriteBatch, 0, 0); //SelectionBuffer.DebugDraw(GraphicsDevice.Viewport.Bounds); try { DwarfGame.SafeSpriteBatchBegin(SpriteSortMode.Immediate, BlendState.NonPremultiplied, Drawer2D.PointMagLinearMin, null, rasterizerState, null, Matrix.Identity); //DwarfGame.SpriteBatch.Draw(Shadows.ShadowTexture, Vector2.Zero, Color.White); if (IsCameraUnderwater()) { Drawer2D.FillRect(DwarfGame.SpriteBatch, GraphicsDevice.Viewport.Bounds, new Color(10, 40, 60, 200)); } Drawer2D.Render(DwarfGame.SpriteBatch, Camera, GraphicsDevice.Viewport); IndicatorManager.Render(gameTime); } finally { DwarfGame.SpriteBatch.End(); } Master.Render(Game, gameTime, GraphicsDevice); DwarfGame.SpriteBatch.GraphicsDevice.ScissorRectangle = DwarfGame.SpriteBatch.GraphicsDevice.Viewport.Bounds; GraphicsDevice.DepthStencilState = DepthStencilState.Default; GraphicsDevice.BlendState = BlendState.Opaque; GamePerformance.Instance.StopTrackPerformance("Render - Misc"); GamePerformance.Instance.StopTrackPerformance("Render - RENDER"); lock (ScreenshotLock) { foreach (Screenshot shot in Screenshots) { TakeScreenshot(shot.FileName, shot.Resolution); } Screenshots.Clear(); } }
/// <summary> /// Called when a frame is to be drawn to the screen /// </summary> /// <param name="gameTime">The current time</param> public void Render(DwarfTime gameTime) { if (!ShowingWorld) { return; } var frustum = Camera.GetDrawFrustum(); var renderables = EnumerateIntersectingObjects(frustum) .Where(r => r.IsVisible && !ChunkManager.IsAboveCullPlane(r.GetBoundingBox())); // Controls the sky fog float x = (1.0f - Sky.TimeOfDay); x = x * x; DefaultShader.FogColor = new Color(0.32f * x, 0.58f * x, 0.9f * x); DefaultShader.LightPositions = LightPositions; CompositeLibrary.Render(GraphicsDevice); CompositeLibrary.Update(); GraphicsDevice.DepthStencilState = DepthStencilState.Default; GraphicsDevice.BlendState = BlendState.Opaque; // Computes the water height. float wHeight = WaterRenderer.GetVisibleWaterHeight(ChunkManager, Camera, GraphicsDevice.Viewport, lastWaterHeight); lastWaterHeight = wHeight; // Draw reflection/refraction images WaterRenderer.DrawReflectionMap(renderables, gameTime, this, wHeight - 0.1f, GetReflectedCameraMatrix(wHeight), DefaultShader, GraphicsDevice); #region Draw Selection Buffer. if (SelectionBuffer == null) { SelectionBuffer = new SelectionBuffer(8, GraphicsDevice); } GraphicsDevice.RasterizerState = RasterizerState.CullNone; GraphicsDevice.DepthStencilState = DepthStencilState.Default; GraphicsDevice.BlendState = BlendState.Opaque; Plane slicePlane = WaterRenderer.CreatePlane(SlicePlane, new Vector3(0, -1, 0), Camera.ViewMatrix, false); if (SelectionBuffer.Begin(GraphicsDevice)) { // Draw the whole world, and make sure to handle slicing DefaultShader.ClipPlane = new Vector4(slicePlane.Normal, slicePlane.D); DefaultShader.ClippingEnabled = true; DefaultShader.View = Camera.ViewMatrix; DefaultShader.Projection = Camera.ProjectionMatrix; DefaultShader.World = Matrix.Identity; //GamePerformance.Instance.StartTrackPerformance("Render - Selection Buffer - Chunks"); ChunkRenderer.RenderSelectionBuffer(DefaultShader, GraphicsDevice, Camera.ViewMatrix); //GamePerformance.Instance.StopTrackPerformance("Render - Selection Buffer - Chunks"); //GamePerformance.Instance.StartTrackPerformance("Render - Selection Buffer - Components"); ComponentRenderer.RenderSelectionBuffer(renderables, gameTime, ChunkManager, Camera, DwarfGame.SpriteBatch, GraphicsDevice, DefaultShader); //GamePerformance.Instance.StopTrackPerformance("Render - Selection Buffer - Components"); //GamePerformance.Instance.StartTrackPerformance("Render - Selection Buffer - Instances"); InstanceRenderer.Flush(GraphicsDevice, DefaultShader, Camera, InstanceRenderMode.SelectionBuffer); //GamePerformance.Instance.StopTrackPerformance("Render - Selection Buffer - Instances"); SelectionBuffer.End(GraphicsDevice); } #endregion // Start drawing the bloom effect if (GameSettings.Default.EnableGlow) { bloom.BeginDraw(); } // Draw the sky GraphicsDevice.Clear(DefaultShader.FogColor); DrawSky(gameTime, Camera.ViewMatrix, 1.0f, DefaultShader.FogColor); // Defines the current slice for the GPU float level = ChunkManager.World.Master.MaxViewingLevel + 0.25f; if (level > VoxelConstants.ChunkSizeY) { level = 1000; } SlicePlane = level; DefaultShader.WindDirection = Weather.CurrentWind; DefaultShader.WindForce = 0.0005f * (1.0f + (float)Math.Sin(Time.GetTotalSeconds() * 0.001f)); // Draw the whole world, and make sure to handle slicing DefaultShader.ClipPlane = new Vector4(slicePlane.Normal, slicePlane.D); DefaultShader.ClippingEnabled = true; //Blue ghost effect above the current slice. DefaultShader.GhostClippingEnabled = true; Draw3DThings(gameTime, DefaultShader, Camera.ViewMatrix); // Now we want to draw the water on top of everything else DefaultShader.ClippingEnabled = true; DefaultShader.GhostClippingEnabled = false; //ComponentManager.CollisionManager.DebugDraw(); DefaultShader.View = Camera.ViewMatrix; DefaultShader.Projection = Camera.ProjectionMatrix; DefaultShader.GhostClippingEnabled = true; // Now draw all of the entities in the game DefaultShader.ClipPlane = new Vector4(slicePlane.Normal, slicePlane.D); DefaultShader.ClippingEnabled = true; if (Debugger.Switches.DrawOcttree) { foreach (var box in OctTree.EnumerateBounds(frustum)) { Drawer3D.DrawBox(box.Item2, Color.Yellow, 1.0f / (float)(box.Item1 + 1), false); } } // Render simple geometry (boxes, etc.) Drawer3D.Render(GraphicsDevice, DefaultShader, Camera, DesignationDrawer, PlayerFaction.Designations, this); DefaultShader.EnableShadows = false; DefaultShader.View = Camera.ViewMatrix; ComponentRenderer.Render(renderables, gameTime, ChunkManager, Camera, DwarfGame.SpriteBatch, GraphicsDevice, DefaultShader, ComponentRenderer.WaterRenderType.None, lastWaterHeight); InstanceRenderer.Flush(GraphicsDevice, DefaultShader, Camera, InstanceRenderMode.Normal); if (Master.CurrentToolMode == GameMaster.ToolMode.BuildZone || Master.CurrentToolMode == GameMaster.ToolMode.BuildWall || Master.CurrentToolMode == GameMaster.ToolMode.BuildObject) { DefaultShader.View = Camera.ViewMatrix; DefaultShader.Projection = Camera.ProjectionMatrix; DefaultShader.SetTexturedTechnique(); GraphicsDevice.BlendState = BlendState.NonPremultiplied; } WaterRenderer.DrawWater( GraphicsDevice, (float)gameTime.TotalGameTime.TotalSeconds, DefaultShader, Camera.ViewMatrix, GetReflectedCameraMatrix(wHeight), Camera.ProjectionMatrix, new Vector3(0.1f, 0.0f, 0.1f), Camera, ChunkManager); ParticleManager.Render(this, GraphicsDevice); DefaultShader.ClippingEnabled = false; if (GameSettings.Default.EnableGlow) { bloom.DrawTarget = UseFXAA ? fxaa.RenderTarget : null; if (UseFXAA) { fxaa.Begin(DwarfTime.LastTime); } bloom.Draw(gameTime.ToRealTime()); if (UseFXAA) { fxaa.End(DwarfTime.LastTime); } } else if (UseFXAA) { fxaa.End(DwarfTime.LastTime); } RasterizerState rasterizerState = new RasterizerState() { ScissorTestEnable = true }; if (Debugger.Switches.DrawSelectionBuffer) { SelectionBuffer.DebugDraw(GraphicsDevice.Viewport.Bounds); } try { DwarfGame.SafeSpriteBatchBegin(SpriteSortMode.Deferred, BlendState.NonPremultiplied, Drawer2D.PointMagLinearMin, null, rasterizerState, null, Matrix.Identity); //DwarfGame.SpriteBatch.Draw(Shadows.ShadowTexture, Vector2.Zero, Color.White); if (IsCameraUnderwater()) { Drawer2D.FillRect(DwarfGame.SpriteBatch, GraphicsDevice.Viewport.Bounds, new Color(10, 40, 60, 200)); } Drawer2D.Render(DwarfGame.SpriteBatch, Camera, GraphicsDevice.Viewport); IndicatorManager.Render(gameTime); } finally { DwarfGame.SpriteBatch.End(); } if (Debugger.Switches.DrawComposites) { Vector2 offset = Vector2.Zero; foreach (var composite in CompositeLibrary.Composites) { offset = composite.Value.DebugDraw(DwarfGame.SpriteBatch, (int)offset.X, (int)offset.Y); } } Master.Render(Game, gameTime, GraphicsDevice); DwarfGame.SpriteBatch.GraphicsDevice.ScissorRectangle = DwarfGame.SpriteBatch.GraphicsDevice.Viewport.Bounds; GraphicsDevice.DepthStencilState = DepthStencilState.Default; GraphicsDevice.BlendState = BlendState.Opaque; lock (ScreenshotLock) { foreach (Screenshot shot in Screenshots) { TakeScreenshot(shot.FileName, shot.Resolution); } Screenshots.Clear(); } }