public XnaComponent( bool enableDepthStencil, bool preferMultiSampling, bool preferAnisotropicFiltering, Int32Rect targetSize = default(Int32Rect), ExitRunScopeBehavior exitRunScopeBehavior = ExitRunScopeBehavior.Stop) { _exitRunScopeBehavior = exitRunScopeBehavior; _graphicsOptions = new XnaGraphicsOptions(enableDepthStencil, preferAnisotropicFiltering, preferMultiSampling); _deviceTransitionScope = new StateScope(); _suppressDrawScope = new StateScope(); _services = new ServiceContainer(); _maximumElapsedTime = TimeSpan.FromMilliseconds(500.0); _time = new XnaTime(); _isFixedTimeStep = false; _updatesSinceRunningSlowly1 = 0x7fffffff; _updatesSinceRunningSlowly2 = 0x7fffffff; _clock = new XnaClock(); _totalGameTime = TimeSpan.Zero; _accumulatedElapsedGameTime = TimeSpan.Zero; _lastFrameElapsedGameTime = TimeSpan.Zero; _targetElapsedTime = TimeSpan.FromTicks(166667); _timer = new XnaTimer(); _targetSize = new Int32Rect(0, 0, Math.Max(1, targetSize.Width), Math.Max(1, targetSize.Height)); _runScope = new StateScope(OnRunScopeIsWithinChanged); }
/// <summary> /// Updates the particle system. /// </summary> public void Update(XnaTime gameTime) { if (gameTime == null) { throw new ArgumentNullException("gameTime"); } _currentTime += (float)gameTime.ElapsedGameTime.TotalSeconds; RetireActiveParticles(); FreeRetiredParticles(); // If we let our timer go on increasing for ever, it would eventually // run out of floating point precision, at which point the particles // would render incorrectly. An easy way to prevent this is to notice // that the time value doesn't matter when no particles are being drawn, // so we can reset it back to zero any time the active queue is empty. if (_firstActiveParticle == _firstFreeParticle) { _currentTime = 0; } if (_firstRetiredParticle == _firstActiveParticle) { _drawCounter = 0; } }
protected override void Present(XnaTime time) { var milliseconds = time.ElapsedGameTime.Milliseconds; _dt = milliseconds / 1000.0f; _sun.Update(time.ElapsedGameTime); var device = Graphics.GraphicsDevice; if (_usePostProcessor) { device.SetRenderTarget(0, _tempBuffer); device.Clear( options: ClearOptions.Target, color: Color.TransparentBlack, depth: 1.0f, stencil: 0); _sun.Render(); _postProcessor.ToneMap(_tempBuffer, BackBuffer, _dt, false, true); device.SetRenderTarget(0, BackBuffer); } else { device.Clear( options: ClearOptions.Target, color: Color.TransparentBlack, depth: 1.0f, stencil: 0); _sun.Render(); } }
public CustomPresentEventArgs([NotNull] XnaTime time) { if (time == null) { throw new ArgumentNullException("time"); } _time = time; }
protected override void Update(XnaTime gameTime) { UpdateExplosions(gameTime); UpdateProjectiles(gameTime); _explosionParticles.Update(gameTime); base.Update(gameTime); }
/// <summary> /// Helper for updating the list of active projectiles. /// </summary> void UpdateProjectiles(XnaTime gameTime) { int i = 0; while (i < _projectiles.Count) { if (!_projectiles[i].Update(gameTime)) { // Remove projectiles at the end of their life. _projectiles.RemoveAt(i); } else { // Advance to the next projectile. i++; } } }
/// <summary> /// Helper for updating the explosions effect. /// </summary> void UpdateExplosions(XnaTime gameTime) { var explosionInterval = ExplosionInterval; if (explosionInterval == null) { return; } _timeToNextProjectile -= gameTime.ElapsedGameTime; if (_timeToNextProjectile <= TimeSpan.Zero) { // Create a new projectile once per second. The real work of moving // and creating particles is handled inside the Projectile class. _projectiles.Add(new Explosion(_explosionParticles)); _timeToNextProjectile += explosionInterval.Value; } }
/// <summary> /// Updates the projectile. /// </summary> public bool Update(XnaTime gameTime) { var elapsedTime = (float)gameTime.ElapsedGameTime.TotalSeconds; // Simple projectile physics. _position += _velocity * elapsedTime; _age += elapsedTime; // If enough time has passed, explode! Note how we pass our velocity // in to the AddParticle method: this lets the explosion be influenced // by the speed and direction of the projectile which created it. if (_age > projectileLifespan) { for (int i = 0; i < numExplosionParticles; i++) { _explosionParticles.AddParticle(_position, Vector3.Zero); } return(false); } return(true); }
protected override void Present(XnaTime time) { var device = Graphics.GraphicsDevice; Clear(); // Compute camera matrices. var aspectRatio = (float)device.Viewport.Width / device.Viewport.Height; var view = Matrix.CreateLookAt( new Vector3(0, 0, -200), new Vector3(0, 0, 0), Vector3.Up); var projection = Matrix.CreatePerspectiveFieldOfView( MathHelper.PiOver4, aspectRatio, 1, 10000); // Pass camera matrices through to the particle system components. _explosionParticles.SetCamera(view, projection); _explosionParticles.Draw(time); }
protected virtual void Update(XnaTime gameTime) { _doneFirstUpdate = true; }
protected virtual void Present(XnaTime time) { }
/// <summary> /// Draws the particle system. /// </summary> public void Draw(XnaTime gameTime) { var device = _graphicsDevice; // Restore the vertex buffer contents if the graphics device was lost. if (_vertexBuffer.IsContentLost) { _vertexBuffer.SetData(_particles); } // If there are any particles waiting in the newly added queue, // we'd better upload them to the GPU ready for drawing. if (_firstNewParticle != _firstFreeParticle) { AddNewParticlesToVertexBuffer(); } // If there are any active particles, draw them now! if (_firstActiveParticle != _firstFreeParticle) { SetParticleRenderStates(device.RenderState); // Set an effect parameter describing the viewport size. This is needed // to convert particle sizes into screen space point sprite sizes. _effectViewportHeightParameter.SetValue(device.Viewport.Height); // Set an effect parameter describing the current time. All the vertex // shader particle animation is keyed off this value. _effectTimeParameter.SetValue(_currentTime); // Set the particle vertex buffer and vertex declaration. device.Vertices[0].SetSource( _vertexBuffer, 0, ParticleVertex.SizeInBytes); device.VertexDeclaration = _vertexDeclaration; // Activate the particle effect. _particleEffect.Begin(SaveStateMode.None); foreach (var pass in _particleEffect.CurrentTechnique.Passes) { pass.Begin(); if (_firstActiveParticle < _firstFreeParticle) { // If the active particles are all in one consecutive range, // we can draw them all in a single call. device.DrawPrimitives( PrimitiveType.PointList, _firstActiveParticle, _firstFreeParticle - _firstActiveParticle); } else { // If the active particle range wraps past the end of the queue // back to the start, we must split them over two draw calls. device.DrawPrimitives( PrimitiveType.PointList, _firstActiveParticle, _particles.Length - _firstActiveParticle); if (_firstFreeParticle > 0) { device.DrawPrimitives( PrimitiveType.PointList, 0, _firstFreeParticle); } } pass.End(); } _particleEffect.End(); // Reset a couple of the more unusual renderstates that we changed, //// so as not to mess up any other subsequent drawing. device.RenderState.PointSpriteEnable = false; device.RenderState.DepthBufferWriteEnable = true; } _drawCounter++; }