private void Draw(DrawState state) { state.GraphicsDevice.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, new Color(0.2f, 0.2f, 0.5f, 1.0f), 1.0f, 0); state.PushProjection(_camera.Projection); _shader.Bind(state); const int TileSize = 44; const int TileSizeOver2 = TileSize / 2; const int TileStepX = 22; const int TileStepY = 22; const int MaxTileDistance = 10; const int MaxTileDistanceTime2 = MaxTileDistance * 2; PresentationParameters pp = state.PresentationParameters; Vector2 cameraOffset = new Vector2(0.5f, 0.5f); Vector2 cameraPosition = state.Camera.Position + cameraOffset; Vector2 viewSize = new Vector2(pp.BackBufferWidth, pp.BackBufferHeight); Vector2 tileCounts = new Vector2(viewSize.X / 22, viewSize.Y / 22); tileCounts.X = Math.Min(tileCounts.X, MaxTileDistanceTime2); tileCounts.Y = Math.Min(tileCounts.Y, MaxTileDistanceTime2); int startX = (int)(cameraPosition.X - tileCounts.X); int startY = (int)(cameraPosition.Y - tileCounts.Y); int endX = (int)(cameraPosition.X + tileCounts.X); int endY = (int)(cameraPosition.Y + tileCounts.Y); Vector2 offset, northVector, eastVector, westVector, southVector, center; int tileZ, eastTileZ, southTileZ, downTileZ; for (int y = startY; y < endY; y++) { offset.X = ((-tileCounts.X / 4) + (startY - y)) * TileStepY; offset.Y = ((tileCounts.Y * 2) + (startY - y)) * TileStepY; BoundingBox bb; for (int x = startX; x < endX; x++) { Tile tile = _maps.Felucca.Tiles.GetLandTile(x, y); Tile tileEast = _maps.Felucca.Tiles.GetLandTile(x - 1, y); Tile tileSouth = _maps.Felucca.Tiles.GetLandTile(x, y + 1); Tile tileDown = _maps.Felucca.Tiles.GetLandTile(x - 1, y + 1); offset.X += TileStepX; offset.Y -= TileStepY; tileZ = tile._z * 4; eastTileZ = tileEast._z * 4; southTileZ = tileSouth._z * 4; downTileZ = tileDown._z * 4; center.X = offset.X; center.Y = offset.Y; northVector.X = center.X; northVector.Y = center.Y - TileSizeOver2 - tileZ; eastVector.X = center.X + TileSizeOver2; eastVector.Y = center.Y - eastTileZ; westVector.X = center.X - TileSizeOver2; westVector.Y = center.Y - southTileZ; southVector.X = center.X; southVector.Y = center.Y + TileSizeOver2 - downTileZ; bb.Min = new Vector3(westVector.X, northVector.Y, 0); bb.Max = new Vector3(eastVector.X, southVector.Y, 0); if (_camera.BoundingFrustum.Intersects(bb)) { _renderer.QueueQuad(state, ref northVector, ref eastVector, ref westVector, ref southVector, _textureFactory.CreateLand(tile._id)); } } } _renderer.Flush(state); state.PopProjection(); }
private void DrawFrame() { try { if (_deviceLost) { _context.InvokeReset(); _deviceLost = false; #if DEBUG _context.PerformanceMonitor.IncreaseLifetimeCounter(LifetimeCounters.DeviceResets); #endif return; } if (_drawState == null) { _drawState = new DrawState(_container); } _drawState.IncrementFrameIndex(); _drawState.FrameTime = _gameTime.FrameTime; _drawState.FrameTimeMs = _gameTime.FrameTimeMs; _drawState.TotalGameTime = _gameTime.TotalGameTime; _drawState.Paused = _gameTime.Paused; #if DEBUG _context.PerformanceMonitor.StartTimer(DeviceTimers.BeforeDraw); #endif OnBeforeDraw(); #if DEBUG _context.PerformanceMonitor.StopTimer(DeviceTimers.BeforeDraw); _context.PerformanceMonitor.StartTimer(DeviceTimers.RenderTimer); #endif ushort stackHeight, stateHeight, cameraHeight, preCull, postCull; _drawState.GetStackHeight(out stackHeight, out stateHeight, out cameraHeight, out preCull, out postCull); _drawState.PrepareForNewFrame(); if (_drawState.BeginScene()) { _screenTarget.BeginWorld(_drawState); _worldRenderChain.Execute(_drawState); _drawState.UnbindShader(); _screenTarget.EndWorld(_drawState); _screenTarget.BeginUI(_drawState); _uiRenderChain.Execute(_drawState); _drawState.UnbindShader(); _screenTarget.EndUI(_drawState); _screenTarget.Combine(_drawState); _drawState.ValidateStackHeight(stackHeight, stateHeight, cameraHeight, preCull, postCull); _drawState.EndScene(); } #if DEBUG _context.PerformanceMonitor.StopTimer(DeviceTimers.RenderTimer); _context.PerformanceMonitor.StartTimer(DeviceTimers.AfterDraw); #endif OnAfterDraw(); #if DEBUG _context.PerformanceMonitor.StopTimer(DeviceTimers.AfterDraw); #endif _context.Present(); } catch (SharpDXException e) { switch (_context.CheckDeviceState()) { case DeviceState.DeviceHung: throw new Exception("Device hung like a horse.", e); case DeviceState.DeviceLost: _deviceLost = true; break; case DeviceState.DeviceRemoved: throw new Exception("Device was removed", e); case DeviceState.OutOfVideoMemory: throw new Exception("Out of video memory", e); default: throw; } } }