Example #1
0
        /// <summary>
        /// Function to handle idle time for the application.
        /// </summary>
        /// <returns><b>true</b> to continue processing, <b>false</b> to stop.</returns>
        private static bool Idle()
        {
            // Rotate our pyramid.
            _angle += 45.0f * GorgonTiming.Delta;

            if (_angle > 360.0f)
            {
                _angle -= 360.0f;
            }


            // This will allow us to animate the center point of our pyramid.
            _heightOffset = _angle.ToRadians().FastSin().Abs();

            // Send the animated variables to their respective shaders.
            UpdatedWorldProjection();

            // Clear our render target.
            _swap.RenderTargetView.Clear(Color.CornflowerBlue);
            _depthStencil.ClearDepth(1.0f);

            _graphics.Submit(_drawCall);

            GorgonExample.BlitLogo(_graphics);

            // Send the contents of the swap chain buffers to the screen.
            _swap.Present(1);

            return(true);
        }
        /// <summary>
        /// Function to render the image into the preview area.
        /// </summary>
        private void RenderImage()
        {
            if ((IsDesignTime) || (_swapChain == null))
            {
                return;
            }

            GorgonTexture2DView image = _previewTexture ?? _defaultTexture;

            _swapChain.RenderTargetView.Clear(BackColor);

            GraphicsContext.Graphics.SetRenderTarget(_swapChain.RenderTargetView);

            _renderer.Begin();

            var   halfClient = new DX.Vector2(ClientSize.Width / 2.0f, ClientSize.Height / 2.0f);
            float scale      = ((float)ClientSize.Width / image.Width).Min((float)ClientSize.Height / image.Height);
            float width      = image.Width * scale;
            float height     = image.Height * scale;
            float x          = halfClient.X - (width / 2.0f);
            float y          = halfClient.Y - (height / 2.0f);

            _renderer.DrawFilledRectangle(new DX.RectangleF(x, y, width, height), GorgonColor.White, image, new DX.RectangleF(0, 0, 1, 1));

            _titleText.LayoutArea = new DX.Size2F(_swapChain.Width, _titleText.Size.Height * 1.5f);
            _titleText.Position   = new DX.Vector2(0, _swapChain.Height - (_titleText.Size.Height * 1.5f).Min(_swapChain.Height * 0.25f));// _swapChain.Height - _titleText.Size.Height);

            _renderer.DrawFilledRectangle(new DX.RectangleF(0, _titleText.Position.Y, _swapChain.Width, _titleText.LayoutArea.Value.Height), new GorgonColor(0, 0, 0, 0.5f));

            _renderer.DrawTextSprite(_titleText);
            _renderer.End();

            _swapChain.Present(1);
        }
Example #3
0
        /// <summary>
        /// Function called during idle time.
        /// </summary>
        /// <returns><b>true</b> to continue execution, <b>false</b> to stop.</returns>
        private bool Idle()
        {
            _swap.RenderTargetView.Clear(GorgonColor.White);

            var windowSize = new DX.Size2F(ClientSize.Width, ClientSize.Height);
            var imageSize  = new DX.Size2F(_texture.Width, _texture.Height);

            // Calculate the scale between the images.
            var scale = new DX.Size2F(windowSize.Width / imageSize.Width, windowSize.Height / imageSize.Height);

            // Only scale on a single axis if we don't have a 1:1 aspect ratio.
            if (scale.Height > scale.Width)
            {
                scale.Height = scale.Width;
            }
            else
            {
                scale.Width = scale.Height;
            }

            // Scale the image.
            var size = new DX.Size2((int)(scale.Width * imageSize.Width), (int)(scale.Height * imageSize.Height));

            // Find the position.
            var bounds = new DX.Rectangle((int)((windowSize.Width / 2) - (size.Width / 2)), (int)((windowSize.Height / 2) - (size.Height / 2)), size.Width, size.Height);

            _graphics.DrawTexture(_texture, bounds);

            GorgonExample.BlitLogo(_graphics);

            _swap.Present(1);

            return(true);
        }
Example #4
0
        /// <summary>
        /// Function called when the application goes into an idle state.
        /// </summary>
        /// <returns><b>true</b> to continue executing, <b>false</b> to stop.</returns>
        private static bool Idle()
        {
            _tileSize = new DX.Size2((int)(_screen.Width / _snowTile.ScaledSize.Width), (int)(_screen.Height / _snowTile.ScaledSize.Height));

            _screen.RenderTargetView.Clear(GorgonColor.White);
            _depthBuffer.Clear(1.0f, 0);

            // We have to pass in a state that allows depth writing and testing. Otherwise the depth buffer won't be used.
            _renderer.Begin(Gorgon2DBatchState.DepthEnabled);

            DrawBackground();

            // Note that the order that we draw here is not important since the depth buffer will sort on our behalf.
            // As mentioned in the description for the example, alpha blending doesn't work all that well with this
            // trick. You'll notice this when the guy walks behind the icicle as the icicle completely obscures the
            // guy even though the icicle has alpha translucency.
            DrawIcicle();

            DrawGuy();

            _renderer.End();

            GorgonExample.DrawStatsAndLogo(_renderer);

            _controller.Update();

            AnimationTransition();

            _screen.Present(1);
            return(true);
        }
Example #5
0
        /// <summary>
        /// Function called when the application goes into an idle state.
        /// </summary>
        /// <returns><b>true</b> to continue executing, <b>false</b> to stop.</returns>
        private static bool Idle()
        {
            if (_lightBrightDir)
            {
                _lightValue += 1.0f * GorgonTiming.Delta;
            }
            else
            {
                _lightValue -= 1.0f * GorgonTiming.Delta;
            }

            if (_torchFrameTime.Milliseconds > 250)
            {
                _torchSprite.TextureRegion =
                    _torchTexture.Texture.ToTexel(new DX.Rectangle(_torchSprite.TextureRegion.Left == 0 ? 56 : 0, 0, 55, _torchTexture.Height));
                _torchFrameTime.Reset();

                _lightValue = _torchSprite.TextureRegion.Left == 0 ? _lightMinMax.Maximum : _lightMinMax.Minimum;
            }

            if (_lightValue < _lightMinMax.Minimum)
            {
                _lightValue     = _lightMinMax.Minimum;
                _lightBrightDir = !_lightBrightDir;
            }

            if (_lightValue > _lightMinMax.Maximum)
            {
                _lightValue     = _lightMinMax.Maximum;
                _lightBrightDir = !_lightBrightDir;
            }

            _lightEffect.Lights[0].Color         = new GorgonColor((_lightValue * 253.0f) / 255.0f, (_lightValue * 248.0f) / 255.0f, (_lightValue * 230.0f) / 255.0f);
            _lightEffect.Lights[0].SpecularPower = (1.0f - (_lightValue / 1.2f)) * 15;

            _finalTarget.Clear(GorgonColor.BlackTransparent);
            _screen.RenderTargetView.Clear(GorgonColor.Black);

            // Render the lit sprite.
            _lightEffect.Render(DrawLitScene, _finalTarget);

            // Blit our final texture to the main screen.
            _graphics.SetRenderTarget(_screen.RenderTargetView);
            _renderer.Begin();
            _renderer.DrawFilledRectangle(new DX.RectangleF(0, 0, _screen.Width, _screen.Height),
                                          GorgonColor.White,
                                          _finalTexture,
                                          new DX.RectangleF(0, 0, 1, 1));

            _renderer.DrawSprite(_torchSprite);

            _renderer.DrawString($"Specular Power: {_lightEffect.Lights[0].SpecularPower:0.0#####}\nLight [c #{GorgonColor.CornFlowerBlue.ToHex()}]Z[/c]: {_lightEffect.Lights[0].Position.Z:0.0}",
                                 new DX.Vector2(0, 64));
            _renderer.End();

            GorgonExample.DrawStatsAndLogo(_renderer);

            _screen.Present(1);
            return(true);
        }
Example #6
0
        /// <summary>
        /// Function to render the data to the panel assigned in the <see cref="SetPanel"/> method.
        /// </summary>
        /// <param name="texture">The texture to render.</param>
        /// <param name="outputTexture">The output texture to render.</param>
        public void Render(GorgonTexture2DView texture, GorgonTexture2DView outputTexture)
        {
            if (_swapChain == null)
            {
                return;
            }

            if (_graphics.RenderTargets[0] != _swapChain.RenderTargetView)
            {
                _graphics.SetRenderTarget(_swapChain.RenderTargetView);
            }

            _swapChain.RenderTargetView.Clear(Color.CornflowerBlue);

            if ((texture == null) ||
                (outputTexture == null))
            {
                _swapChain.Present(1);
                return;
            }

            // Get aspect ratio.
            var scale = new DX.Size2F((_swapChain.Width * 0.5f) / texture.Width, (float)_swapChain.Height / texture.Height);

            // Only scale on a single axis if we don't have a 1:1 aspect ratio.
            if (scale.Height > scale.Width)
            {
                scale.Height = scale.Width;
            }
            else
            {
                scale.Width = scale.Height;
            }

            // Scale the image.
            var size = new DX.Size2((int)(scale.Width * texture.Width), (int)(scale.Height * texture.Height));

            // Find the position.
            var bounds = new DX.Rectangle((_swapChain.Width / 4) - (size.Width / 2), ((_swapChain.Height / 2) - (size.Height / 2)), size.Width, size.Height);

            _graphics.DrawTexture(texture, bounds, blendState: GorgonBlendState.Default, samplerState: GorgonSamplerState.PointFiltering);

            bounds = new DX.Rectangle((_swapChain.Width - (_swapChain.Width / 4)) - (size.Width / 2), ((_swapChain.Height / 2) - (size.Height / 2)), size.Width, size.Height);
            _graphics.DrawTexture(outputTexture, bounds, blendState: GorgonBlendState.Default, samplerState: GorgonSamplerState.PointFiltering);

            _swapChain.Present(1);
        }
Example #7
0
        /// <summary>
        /// Function for the main idle loop.
        /// </summary>
        /// <remarks>This is used as the main loop for the application.  All drawing and logic can go in here.</remarks>
        /// <returns><b>true</b> to keep running, <b>false</b> to exit.</returns>
        private static bool Idle()
        {
            if (!_paused)
            {
                // Update the simulation at our desired frame rate.
                if (GorgonTiming.Delta < MinSimulationFPS)
                {
                    _accumulator += GorgonTiming.Delta;
                }
                else
                {
                    _accumulator += MinSimulationFPS;
                }

                while (_accumulator >= MaxSimulationFPS)
                {
                    Transform(MaxSimulationFPS);
                    _accumulator -= MaxSimulationFPS;
                }
            }

            // Begin our rendering.
            _2D.Begin();
            DrawBackground();
            _2D.End();

            if (_blur.BlurRadius == 0)
            {
                _2D.Begin();
                DrawNoBlur();
                _2D.End();
            }
            else
            {
                DrawBlurred();
            }

            _2D.Begin();
            if (_showHelp)
            {
                _2D.DrawTextSprite(_helpTextSprite);
            }

            DrawOverlay();
            _2D.End();

            GorgonExample.DrawStatsAndLogo(_2D);

            _mainScreen.Present();

            _graphics.ResetDrawCallStatistics();

            return(true);
        }
Example #8
0
        /// <summary>
        /// Function to present the rendering to the main window.
        /// </summary>
        private static void Present()
        {
            if (_graphics.RenderTargets[0] != _screen.RenderTargetView)
            {
                _graphics.SetRenderTarget(_screen.RenderTargetView);
            }

            GorgonExample.DrawStatsAndLogo(_renderer);

            _screen.Present(1);
        }
Example #9
0
        /// <summary>
        /// Function to handle idle time for the application.
        /// </summary>
        /// <returns><b>true</b> to continue processing, <b>false</b> to stop.</returns>
        private static bool Idle()
        {
            // Animate the ball.
            UpdateBall();

            // Clear to our gray color and clear out the depth buffer.
            _swap.RenderTargetView.Clear(Color.FromArgb(173, 173, 173));
            //_depthBuffer.Clear(0.0f, 0);
            _depthBuffer.Clear(0.0f, 0);

            // Render the back and floor planes.
            // ReSharper disable once ForCanBeConvertedToForeach
            for (int i = 0; i < _planes.Length; ++i)
            {
                RenderModel(_planes[i]);
            }

            // Render the ball.
            _sphere.Material.Diffuse = GorgonColor.White;
            RenderModel(_sphere);

            // Remember the position and rotation so we can restore them later.
            DX.Vector3 spherePosition = _sphere.Position;
            DX.Vector3 sphereRotation = _sphere.Rotation;

            // Offset the position of the ball so we can fake a shadow under the ball.
            _sphere.Position = new DX.Vector3(spherePosition.X + 0.25f, spherePosition.Y - 0.125f, spherePosition.Z + 0.5f);
            // Scale on the z-axis so the ball "shadow" has no real depth, and on the x & y to make it look slightly bigger.
            _sphere.Scale = new DX.Vector3(1.155f, 1.155f, 0.001f);
            // Reset the rotation so we don't rotate our flattened ball "shadow" (it'd look real weird if it rotated).
            _sphere.Rotation = DX.Vector3.Zero;
            // Render as black with alpha of 0.5 to simulate a shadow.
            _sphere.Material.Diffuse = new GorgonColor(0, 0, 0, 0.5f);

            // Render the shadow.
            RenderModel(_sphere);

            // Restore our original positioning so we can render the ball in the correct place on the next frame.
            _sphere.Position = spherePosition;
            // Reset scale on the z-axis so the ball so it'll be normal for the next frame.
            _sphere.Scale = DX.Vector3.One;
            // Reset the rotation so it'll be in the correct place on the next frame.
            _sphere.Rotation = sphereRotation;

            // Draw our text.
            // Use this to show how incredibly slow and terrible my 3D code is.
            GorgonExample.DrawStatsAndLogo(_2D);

            // Now we flip our buffers.
            // We need to this or we won't see anything.
            _swap.Present(1);

            return(true);
        }
Example #10
0
        /// <summary>
        /// Main application loop.
        /// </summary>
        /// <returns><b>true</b> to continue processing, <b>false</b> to stop.</returns>
        private static bool Idle()
        {
            ProcessKeys();

            _swapChain.RenderTargetView.Clear(Color.CornflowerBlue);
            _depthBuffer.Clear(1.0f, 0);

            _cloudRotation += 2.0f * GorgonTiming.Delta;
            _objRotation   += 50.0f * GorgonTiming.Delta;

            if (_cloudRotation > 359.9f)
            {
                _cloudRotation -= 359.9f;
            }

            if (_objRotation > 359.9f)
            {
                _objRotation -= 359.9f;
            }

            _triangle.Material.TextureOffset = new DX.Vector2(0, _triangle.Material.TextureOffset.Y - (0.125f * GorgonTiming.Delta));

            if (_triangle.Material.TextureOffset.Y < 0.0f)
            {
                _triangle.Material.TextureOffset = new DX.Vector2(0, 1.0f + _triangle.Material.TextureOffset.Y);
            }

            _plane.Material.TextureOffset = _triangle.Material.TextureOffset;

            _icoSphere.Rotation = new DX.Vector3(0, _icoSphere.Rotation.Y + (4.0f * GorgonTiming.Delta), 0);
            _cube.Rotation      = new DX.Vector3(_objRotation, _objRotation, _objRotation);
            _sphere.Position    = new DX.Vector3(-2.0f, (_objRotation.ToRadians().Sin().Abs() * 2.0f) - 1.10f, 0.75f);
            _sphere.Rotation    = new DX.Vector3(_objRotation, _objRotation, 0);
            _clouds.Rotation    = new DX.Vector3(0, _cloudRotation, 0);

            _renderer.Render();

            _2DRenderer.Begin();
            _textSprite.Text = $@"FPS: {GorgonTiming.FPS:0.0}, Delta: {(GorgonTiming.Delta * 1000):0.000} msec. " +
                               $@"Tris: {
		                               ((_triangle.TriangleCount) + (_plane.TriangleCount) + (_cube.TriangleCount) + (_sphere.TriangleCount) + (_icoSphere.TriangleCount) +
		                                (_clouds.TriangleCount))
		                           :0} "         +
                               $@"CamRot: {_cameraRotation} Mouse: {_mouse?.Position.X:0}x{_mouse?.Position.Y:0} Sensitivity: {_sensitivity:0.0##}";
            _2DRenderer.DrawTextSprite(_textSprite);
            _2DRenderer.End();

            GorgonExample.DrawStatsAndLogo(_2DRenderer);

            _swapChain.Present();

            return(true);
        }
Example #11
0
        /// <summary>
        /// Function to do perform processing for the application during idle time.
        /// </summary>
        /// <returns><b>true</b> to continue execution, <b>false</b> to stop.</returns>
        private static bool Idle()
        {
            GorgonSprite shadowSprite = _fgSprite == _sprite2 ? _shadowSprites[1] : _shadowSprites[0];

            // Draw our background that includes our background texture, and the sprite that's currently in the background (along with its shadow).
            // Blurring may or may not be applied depending on whether the user has applied it with the mouse wheel.
            DrawBlurredBackground();

            // Reset scales for our sprites. Foreground sprites will be larger than our background ones.
            shadowSprite.Scale = _fgSprite.Scale = DX.Vector2.One;

            // Ensure we're on the "screen" when we render.
            _graphics.SetRenderTarget(_screen.RenderTargetView);

            _renderer.Begin();

            // Draw our blurred (or not) background.
            _renderer.DrawFilledRectangle(new DX.RectangleF(0, 0, _screen.Width, _screen.Height),
                                          GorgonColor.White,
                                          _blurTexture,
                                          new DX.RectangleF(0, 0, 1, 1));

            // Draw an ellipse to indicate our light source.
            var lightPosition = new DX.RectangleF((_screen.Width / 2.0f) - 10, (_screen.Height / 2.0f) - 10, 20, 20);

            _renderer.DrawFilledEllipse(lightPosition, GorgonColor.White, 0.5f);

            // Draw the sprite and its corresponding shadow.
            // We'll adjust the shadow position to be altered by our distance from the light source, and the quadrant of the screen that we're in.
            shadowSprite.Position = _fgSprite.Position + (new DX.Vector2(_fgSprite.Position.X - (_screen.Width / 2.0f), _fgSprite.Position.Y - (_screen.Height / 2.0f)) * 0.125f);

            _renderer.DrawSprite(shadowSprite);
            _renderer.DrawSprite(_fgSprite);

            if (_showHelp)
            {
                _renderer.DrawString(HelpText, new DX.Vector2(2, 2), _helpFont, GorgonColor.White);
            }

            _renderer.End();

            GorgonExample.DrawStatsAndLogo(_renderer);

            _screen.Present(1);

            return(true);
        }
Example #12
0
        /// <summary>
        /// Function to handle idle time for the application.
        /// </summary>
        /// <returns><b>true</b> to continue processing, <b>false</b> to stop.</returns>
        private static bool Idle()
        {
            // This will clear the swap chain to the specified color.
            _swap.RenderTargetView.Clear(Color.CornflowerBlue);

            // Draw our triangle.
            _graphics.Submit(_drawCall);

            GorgonExample.BlitLogo(_graphics);

            // Now we flip our buffers on the swap chain.
            // We need to this or we won't see anything at all except the standard window background color. Clearly, we don't want that.
            // This method will take the current frame back buffer and flip it to the front buffer (the window). If we had more than one swap chain tied to multiple
            // windows, then we'd need to do this for every swap chain.
            _swap.Present(1);

            return(true);
        }
Example #13
0
        /// <summary>
        /// Function called during CPU idle time.
        /// </summary>
        /// <returns><b>true</b> to continue, <b>false</b> to stop.</returns>
        private static bool Idle()
        {
            _shipDeux.UserInput(_keyboard.KeyStates);
            _shipDeux.Update();

            _ship.UserInput(_keyboard.KeyStates);
            _ship.Update();

            _sceneRenderer.Render();

            // Render the final image back to our swap chain.
            _graphics.SetRenderTarget(_screen.RenderTargetView);
            _renderer.Begin(Gorgon2DBatchState.NoBlend);

            // Copy our final rendering into the swap chain target.
            // Because we use a fixed render target size for our rendering, we'll need to stretch the view to accomodate the swap chain area.
            // We also need to ensure our aspect ratio stays correct. Because of this, you may see black bars on the top/bottom or left/right of the swap chain image.
            float newWidth  = _screen.Width;
            float newHeight = (newWidth / _mainRtvAspect.X);

            if (newHeight > _screen.Height)
            {
                newHeight = _screen.Height;
                newWidth  = (newHeight * _mainRtvAspect.X);
            }

            var destRegion = new DX.RectangleF(_screen.Width * 0.5f - newWidth * 0.5f, _screen.Height * 0.5f - newHeight * 0.5f, newWidth, newHeight);

            _screen.RenderTargetView.Clear(GorgonColor.Black);
            _renderer.DrawFilledRectangle(destRegion,
                                          GorgonColor.White,
                                          _mainSrv,
                                          new DX.RectangleF(0, 0, 1, 1),
                                          textureSampler: GorgonSamplerState.Default);
            _renderer.End();

            RenderGui(destRegion);

            _screen.Present(1);
            return(true);
        }
Example #14
0
        /// <summary>
        /// Function to perform operations while the CPU is idle.
        /// </summary>
        /// <returns><b>true</b> to continue processing, <b>false</b> to stop.</returns>
        private static bool Idle()
        {
            // Set the initial background color, we won't be clearing again...
            _screen.RenderTargetView.Clear(GorgonColor.CornFlowerBlue);

            if (!_mp3Player.IsPlaying)
            {
                PlayAudio();
            }

            if (_animController.CurrentAnimation == null)
            {
                _animController.Play(_animatedSprite, _animation);
            }

            _graphics.SetRenderTarget(_target);
            _renderer.Begin(_targetBatchState);
            _renderer.DrawSprite(_animatedSprite);
            _renderer.End();

            _graphics.SetRenderTarget(_screen.RenderTargetView);
            _renderer.Begin();
            _renderer.DrawFilledRectangle(new DX.RectangleF(0, 0, _screen.Width, _screen.Height),
                                          GorgonColor.White,
                                          _targetView,
                                          new DX.RectangleF(0, 0, 1, 1));
            _renderer.End();

            GorgonExample.DrawStatsAndLogo(_renderer);

            // We need to call this once per frame so the animation will transition properly.
            _animController.Update();

            _screen.Present(1);

            return(true);
        }
Example #15
0
        /// <summary>
        /// Function to process the example functionality during idle time.
        /// </summary>
        /// <returns><b>true</b> to continue, <b>false</b> to stop.</returns>
        private bool Idle()
        {
            _leftPanel.RenderTargetView.Clear(GroupControl1.BackColor);
            _rightPanel.RenderTargetView.Clear(GroupControl2.BackColor);

            _graphics.SetRenderTarget(_leftPanel.RenderTargetView);

            _renderer.Begin();
            _torusLeft.Scale    = _scale;
            _torusLeft.Position = new DX.Vector2(_leftPanel.Width / 2.0f, _leftPanel.Height / 2.0f);
            _renderer.DrawSprite(_torusLeft);
            _renderer.End();

            GorgonExample.DrawStatsAndLogo(_renderer);

            _graphics.SetRenderTarget(_rightPanel.RenderTargetView);

            _renderer.Begin();
            _torusLeft.Scale = DX.Vector2.One;

            _torusRight.Color    = GorgonColor.RedPure;
            _torusRight.Position = new DX.Vector2((_rightPanel.Width / 2.0f) - 64, (_rightPanel.Height / 2.0f) - 64);
            _renderer.DrawSprite(_torusRight);

            _torusRight.Color    = GorgonColor.GreenPure;
            _torusRight.Position = new DX.Vector2((_rightPanel.Width / 2.0f) + 64, (_rightPanel.Height / 2.0f) - 64);
            _renderer.DrawSprite(_torusRight);

            _torusRight.Color    = GorgonColor.BluePure;
            _torusRight.Position = new DX.Vector2((_rightPanel.Width / 2.0f) - 64, (_rightPanel.Height / 2.0f) + 64);
            _renderer.DrawSprite(_torusRight);

            _torusRight.Color    = GorgonColor.White;
            _torusRight.Position = new DX.Vector2((_rightPanel.Width / 2.0f) + 64, (_rightPanel.Height / 2.0f) + 64);
            _renderer.DrawSprite(_torusRight);

            _renderer.DrawString("\u2190Drag me!", new DX.Vector2(0, _rightPanel.Height / 4.0f), _appFont, GorgonColor.White);

            if (_controllerRight.State != AnimationState.Playing)
            {
                _renderer.DrawString("Speed: Stopped", new DX.Vector2(0, 64), _appFont, GorgonColor.White);
            }
            else
            {
                _renderer.DrawString($"Speed: {TrackSpeed.Value / 5.0f:0.0#}", new DX.Vector2(0, 64), _appFont, GorgonColor.White);
            }

            _renderer.End();

            GorgonExample.DrawStatsAndLogo(_renderer);

            _leftPanel.Present(1);
            _rightPanel.Present(1);

            _torusAnim.Speed = 1.0f;
            _controllerLeft.Update();

            if (_controllerRight.State != AnimationState.Playing)
            {
                _controllerRight.Resume();
                _controllerRight.Time = (TrackSpeed.Value / 10.0f) * _torusAnim.Length;
                _controllerRight.Pause();
            }
            else
            {
                _torusAnim.Speed = TrackSpeed.Value / 5.0f;
                _controllerRight.Update();
            }

            return(true);
        }
Example #16
0
        /// <summary>
        /// Function to handle idle time processing.
        /// </summary>
        /// <returns><b>true</b> to continue processing, <b>false</b> to stop.</returns>
        private bool Idle()
        {
            int width  = ClientSize.Width;
            int height = ClientSize.Height;

            _screen.RenderTargetView.Clear(Color.FromArgb(250, 245, 220));

            // Reset the text position.
            if (_poetry.Position.Y < -_poetry.Size.Height)
            {
                _textPosition = new DX.Vector2(0, height + _textFont.LineHeight);
            }

            // Scroll up.
            _textPosition.Y -= (25.0f * GorgonTiming.Delta);

            // Alter blur value.
            _blurAmount += _blurDelta * GorgonTiming.Delta;

            if (_blurAmount < 0.0f)
            {
                _blurAmount = 0.0f;
                _blurDelta  = -_blurDelta;
            }

            if (_blurAmount > 64)
            {
                _blurAmount = 64;
                _blurDelta  = -_blurDelta;
            }

            int index = 0;

            ResetBlur();

            if (_blurAmount > 0)
            {
                // Blur for the count we specify.
                int blurCount = (int)_blurAmount;
                for (int i = 0; i < blurCount; ++i)
                {
                    int imageIndex  = index = i % 2;
                    int targetIndex = index == 0 ? 1 : 0;
                    _blurEffect.Render((_, __, ___) => _renderer.DrawFilledRectangle(new DX.RectangleF(0, 0, _blurredTarget[0].Width, _blurredTarget[0].Height),
                                                                                     GorgonColor.White,
                                                                                     _blurredImage[imageIndex],
                                                                                     new DX.RectangleF(0, 0, 1, 1)),
                                       _blurredTarget[targetIndex]);
                }
            }

            // Switch back to our screen for rendering.
            _graphics.SetRenderTarget(_screen.RenderTargetView);


            // Draw the base.
            _renderer.Begin();

            // Draw text.
            _poetry.Position = _textPosition;
            _renderer.DrawTextSprite(_poetry);

            _sprites[0].Position = new DX.Vector2(width / 4, height / 4);

            // Draw motherships.
            _sprites[1].Position = new DX.Vector2(width - (width / 4), height / 4);

            _renderer.DrawSprite(_sprites[0]);
            _renderer.DrawSprite(_sprites[1]);

            // Draw our blurred image (we could have used a sprite here as well, but this works just as well).
            _renderer.DrawFilledRectangle(new DX.RectangleF((width / 2) - (_blurredImage[0].Width / 2.0f),
                                                            (height / 2) - (_blurredImage[0].Height / 2.0f),
                                                            _blurredImage[0].Width,
                                                            _blurredImage[0].Height),
                                          GorgonColor.White,
                                          _blurredImage[index],
                                          new DX.RectangleF(0, 0, 1, 1));

            // Draw help text.
            if (_showHelp)
            {
                _renderer.DrawTextSprite(_helpText);
            }

            // Show our rendering statistics.
            if (_showStats)
            {
                var rectPosition = new DX.RectangleF(0, 0, width, (_helpFont.FontHeight * 2.0f) + 2.0f);
                _renderer.DrawFilledRectangle(rectPosition, Color.FromArgb(192, Color.Black));
                _renderer.DrawLine(rectPosition.X, rectPosition.Bottom, rectPosition.Width, rectPosition.Bottom, Color.White);
                _renderer.DrawString($"FPS: {GorgonTiming.FPS:0.0}\nFrame Delta: {(GorgonTiming.Delta * 1000):0.0##} msec.",
                                     DX.Vector2.Zero,
                                     _helpFont,
                                     GorgonColor.White);
            }

            _renderer.End();

            GorgonExample.ShowStatistics = _showStats;
            GorgonExample.DrawStatsAndLogo(_renderer);

            _screen.Present(1);
            return(true);
        }
Example #17
0
        /// <summary>
        /// Function to perform operations while the CPU is idle.
        /// </summary>
        /// <returns><b>true</b> to continue processing, <b>false</b> to stop.</returns>
        private static bool Idle()
        {
            _postTarget1.Clear(GorgonColor.Black);

            DX.Vector2 textureSize = _background.Texture.ToTexel(new DX.Vector2(_postTarget1.Width, _postTarget1.Height));

            // Blit the background texture.
            _graphics.SetRenderTarget(_postTarget1);
            _renderer.Begin();
            _renderer.DrawFilledRectangle(new DX.RectangleF(0, 0, _postTarget1.Width, _postTarget1.Height),
                                          GorgonColor.White,
                                          _background,
                                          new DX.RectangleF(_backgroundOffset.X, _backgroundOffset.Y, textureSize.X, textureSize.Y));
            _shipSprite.Color = new GorgonColor(GorgonColor.White, _cloakController.Opacity);
            _renderer.DrawSprite(_shipSprite);
            _renderer.End();

            // No sense in rendering the effect if it's not present.
            float strength = _cloakController.CloakAmount;

            if (strength > 0.0f)
            {
                // Don't bother recording the current state, we're going to be updating it shortly, so it'd be redundant.
                _displacement.Strength = strength;
                _displacement.Render((passIndex, _, __) => DrawDisplacement(passIndex),
                                     _postTarget2);
            }
            else
            {
                // Send the undisplaced image to the 2nd post process target.
                _graphics.SetRenderTarget(_postTarget2);

                _renderer.Begin();
                _renderer.DrawFilledRectangle(new DX.RectangleF(0, 0, _postTarget1.Width, _postTarget1.Height),
                                              GorgonColor.White,
                                              _postView1,
                                              new DX.RectangleF(0, 0, 1, 1));
                _renderer.End();
            }

            // Smooth our results.
            int blurRadiusUpdate = GorgonRandom.RandomInt32(0, 1000000);

            if (blurRadiusUpdate > 997000)
            {
                _gaussBlur.BlurRadius = (_gaussBlur.BlurRadius + 1).Min(_gaussBlur.MaximumBlurRadius / 2);
            }
            else if (blurRadiusUpdate < 3000)
            {
                _gaussBlur.BlurRadius = (_gaussBlur.BlurRadius - 1).Max(1);
            }

            // If we didn't blur (radius = 0), then just use the original view.
            if (_gaussBlur.BlurRadius > 0)
            {
                _gaussBlur.Render((_, __, outputSize) =>
                {
                    _renderer.DrawFilledRectangle(new DX.RectangleF(0, 0, outputSize.Width, outputSize.Height),
                                                  GorgonColor.White,
                                                  _postView2,
                                                  new DX.RectangleF(0, 0, 1, 1));
                },
                                  _postTarget2);
            }

            // Render as an old film effect.
            _oldFilm.Time = GorgonTiming.SecondsSinceStart * 2;
            DX.Vector2 offset = DX.Vector2.Zero;
            if (GorgonRandom.RandomInt32(0, 100) > 95)
            {
                offset = new DX.Vector2(GorgonRandom.RandomSingle(-2.0f, 2.0f), GorgonRandom.RandomSingle(-1.5f, 1.5f));
            }

            _oldFilm.Render((_, __, size) =>
                            _renderer.DrawFilledRectangle(new DX.RectangleF(offset.X, offset.Y, size.Width, size.Height),
                                                          GorgonColor.White,
                                                          _postView2,
                                                          new DX.RectangleF(0, 0, 1, 1)),
                            _postTarget1);

            // Send to our screen.
            _screen.RenderTargetView.Clear(GorgonColor.Black);
            _graphics.SetRenderTarget(_screen.RenderTargetView);

            _renderer.Begin(Gorgon2DBatchState.NoBlend);
            if (GorgonRandom.RandomInt32(0, 100) < 2)
            {
                _finalBrightness = GorgonRandom.RandomSingle(0.65f, 1.0f);
            }

            _renderer.DrawFilledRectangle(new DX.RectangleF(0, 0, _finalView.Width, _finalView.Height),
                                          new GorgonColor(_finalBrightness, _finalBrightness, _finalBrightness, 1.0f),
                                          _postView1,
                                          new DX.RectangleF(0, 0, 1, 1));
            _renderer.End();

            _renderer.Begin();
            if (_showHelp)
            {
                _renderer.DrawString(HelpText, new DX.Vector2(0, 64), color: new GorgonColor(1.0f, 1.0f, 0));
            }
            _renderer.End();

            GorgonExample.DrawStatsAndLogo(_renderer);

            // Flip our back buffers over.
            _screen.Present(1);

            _cloakController.Update();

            return(true);
        }
Example #18
0
        /// <summary>
        /// Function called when the application goes into an idle state.
        /// </summary>
        /// <returns><b>true</b> to continue executing, <b>false</b> to stop.</returns>
        private static bool Idle()
        {
            _angle1 += 45.0f * GorgonTiming.Delta;
            _angle2 -= 30.0f * GorgonTiming.Delta;

            if (_angle1 > 360.0f)
            {
                _angle1 -= 360.0f;
            }

            if (_angle2 < 0.0f)
            {
                _angle2 = 360.0f + _angle2;
            }

            _screen.RenderTargetView.Clear(new GorgonColor(0, 0, 0.2f));

            // Draw standard sprites.
            _renderer.Begin();

            _renderer.DrawString("Polygonal Sprite",
                                 new DX.Vector2((_screen.Width / 4.0f) - (_polySprite.Size.Width * 0.5f),
                                                (_screen.Height / 4.0f) - (_polySprite.Size.Height * 0.5f) - _renderer.DefaultFont.LineHeight));

            _renderer.DrawString("Polygonal Sprite (Wireframe)",
                                 new DX.Vector2(_screen.Width - (_screen.Width / 4.0f) - (_polySprite.Size.Width * 0.5f),
                                                (_screen.Height / 4.0f) - (_polySprite.Size.Height * 0.5f) - _renderer.DefaultFont.LineHeight));

            _renderer.DrawString("Rectangular Sprite",
                                 new DX.Vector2((_screen.Width / 4.0f) - (_polySprite.Size.Width * 0.5f),
                                                _screen.Height - (_screen.Height / 4.0f) - (_polySprite.Size.Height * 0.5f) - _renderer.DefaultFont.LineHeight));

            _renderer.DrawString("Rectangular Sprite (Wireframe)",
                                 new DX.Vector2(_screen.Width - (_screen.Width / 4.0f) - (_polySprite.Size.Width * 0.5f),
                                                _screen.Height - (_screen.Height / 4.0f) - (_polySprite.Size.Height * 0.5f) - _renderer.DefaultFont.LineHeight));

            _normalSprite.Texture  = _texture;
            _normalSprite.Angle    = _angle1;
            _normalSprite.Position = new DX.Vector2(_screen.Width / 4.0f, _screen.Height - (_screen.Height / 4.0f));

            _polySprite.Texture  = _texture;
            _polySprite.Angle    = _angle2;
            _polySprite.Position = new DX.Vector2(_screen.Width / 4.0f, (_screen.Height / 4.0f));

            _renderer.DrawSprite(_normalSprite);
            _renderer.DrawPolygonSprite(_polySprite);

            _renderer.End();

            // Draw wireframe versions.
            _renderer.Begin(Gorgon2DBatchState.WireFrameNoCulling);

            _normalSprite.Texture  = null;
            _normalSprite.Angle    = _angle2;
            _normalSprite.Position = new DX.Vector2(_screen.Width - (_screen.Width / 4.0f), _screen.Height - (_screen.Height / 4.0f));

            _polySprite.Texture  = null;
            _polySprite.Angle    = _angle1;
            _polySprite.Position = new DX.Vector2(_screen.Width - (_screen.Width / 4.0f), (_screen.Height / 4.0f));

            _renderer.DrawSprite(_normalSprite);
            _renderer.DrawPolygonSprite(_polySprite);

            _renderer.End();

            GorgonExample.DrawStatsAndLogo(_renderer);

            _screen.Present(1);

            return(true);
        }
Example #19
0
        /// <summary>
        /// Function to handle idle time for the application.
        /// </summary>
        /// <returns><b>true</b> to continue processing, <b>false</b> to stop.</returns>
        private static bool Idle()
        {
            // This will clear the swap chain to the specified color.
            // For our example, we'll cycle through multiple colors so we don't end up with a boring old screen with a static color. This will also prove that our
            // swap chain is working and rendering data to the window.

            // Set up the clear to clear the upper left and lower right of the swap chain:
            switch (_clearPattern)
            {
            case 1:
                _clearRegions[0] = new DX.Rectangle(0, 0, _swap.Width / 2, _swap.Height / 2);
                _clearRegions[1] = new DX.Rectangle(_swap.Width / 2, _swap.Height / 2, _swap.Width / 2, _swap.Height / 2);
                _swap.RenderTargetView.Clear(_clearColor, _clearRegions);
                break;

            case 2:
                _clearRegions[0] = new DX.Rectangle(_swap.Width / 2, 0, _swap.Width / 2, _swap.Height / 2);
                _clearRegions[1] = new DX.Rectangle(0, _swap.Height / 2, _swap.Width / 2, _swap.Height / 2);
                _swap.RenderTargetView.Clear(_clearColor, _clearRegions);
                break;

            default:
                _swap.RenderTargetView.Clear(_clearColor);
                break;
            }

            // This specifies how much color to apply to the channel.
            // We're using the GorgonTiming.Delta property here to retrieve the number of seconds that it takes to draw a single frame. This allows us to smooth
            // the animation speed by basing it on the frame rate of the device. If we didn't do this, the colors would cycle way too quickly.
            _channelValue = GorgonTiming.Delta * _direction * 0.4f;

            switch (_channel)
            {
            case 0:
                _channelValue = _clearColor.Red + _channelValue;
                _clearColor   = new GorgonColor(_channelValue, 0, 0);
                break;

            case 1:
                _channelValue = _clearColor.Green + _channelValue;
                _clearColor   = new GorgonColor(0, _channelValue, 0);
                break;

            case 2:
                _channelValue = _clearColor.Blue + _channelValue;
                _clearColor   = new GorgonColor(0, 0, _channelValue);
                break;
            }

            // If we've exceeded the min/max amount of color for the channel, move on to the next.
            if (_channelValue > 1.0f)
            {
                _direction    = -1;
                _channelValue = 1.0f;
            }

            if (_channelValue < 0.0f)
            {
                _direction    = 1;
                _channelValue = 0.0f;
                _channel     += _channelDirection;
            }

            // Flip directions and set to the middle channel.
            if (_channel > 2)
            {
                _channel          = 1;
                _channelDirection = -1;

                ++_clearPattern;
                if (_clearPattern > 2)
                {
                    _clearPattern = 0;
                }
            }

            if (_channel < 0)
            {
                _channel          = 1;
                _channelDirection = 1;

                ++_clearPattern;
                if (_clearPattern > 2)
                {
                    _clearPattern = 0;
                }
            }

            GorgonExample.BlitLogo(_graphics);

            // Now we flip our buffers on the swap chain.
            // We need to this or we won't see anything at all except the standard window background color. Clearly, we don't want that.
            // This method will take the current frame back buffer and flip it to the front buffer (the window). If we had more than one swap chain tied to multiple
            // windows, then we'd need to do this for every swap chain.
            _swap.Present();

            return(true);
        }
Example #20
0
        /// <summary>
        /// Function to process during idle time.
        /// </summary>
        /// <returns><b>true</b> to continue processing, <b>false</b> to end processing.</returns>
        private bool Gorgon_Idle()
        {
            // Cursor position.
            Point mousePosition  = PointToClient(!_useWinFormsInput ? _mouse.Position : Cursor.Position);
            var   cursorPosition = new DX.Vector2(mousePosition.X, mousePosition.Y);

            if (!_useWinFormsInput)
            {
                Cursor.Position = PointToScreen(mousePosition);
            }

            // Dump to the screen.
            _2D.Begin(_noBlending);
            _2D.DrawFilledRectangle(new DX.RectangleF(0, 0, _backBuffer.Width, _backBuffer.Height), GorgonColor.White, _backBufferView, new DX.RectangleF(0, 0, 1, 1));
            _2D.End();

            if (_joystick != null)
            {
                // Poll the joystick.
                _joystick.Poll();

                GorgonRange xAxisRange = _joystick.Info.AxisInfo[GamingDeviceAxis.XAxis].Range;
                GorgonRange yAxisRange = _joystick.Info.AxisInfo[GamingDeviceAxis.YAxis].Range;

                // Adjust position to match screen coordinates.
                cursorPosition = new DX.Vector2(_joystick.Axis[GamingDeviceAxis.XAxis].Value - xAxisRange.Minimum,
                                                _joystick.Axis[GamingDeviceAxis.YAxis].Value - yAxisRange.Minimum);
                cursorPosition.X = cursorPosition.X / (xAxisRange.Range + 1) * _screen.Width;
                cursorPosition.Y = _screen.Height - (cursorPosition.Y / (yAxisRange.Range + 1) * _screen.Height);
            }


            // Draw cursor.
            _2D.Begin(_inverted);
            if (_radius > 3.0f)
            {
                _2D.DrawFilledEllipse(new DX.RectangleF(cursorPosition.X - (_radius / 2.0f), cursorPosition.Y - (_radius / 2.0f), _radius, _radius), Color.White);
            }
            else
            {
                _2D.DrawFilledRectangle(new DX.RectangleF(cursorPosition.X - (_radius / 2.0f), cursorPosition.Y - (_radius / 2.0f), _radius, _radius), Color.White);
            }
            _2D.End();

            // If we have a joystick button down, then draw a black dot.
            if ((_joystick != null) && (_joystick.Button[0] == GamingDeviceButtonState.Down))
            {
                var penPosition = new DX.RectangleF(cursorPosition.X - (_radius / 2.0f), cursorPosition.Y - (_radius / 2.0f), _radius, _radius);
                _graphics.SetRenderTarget(_backBuffer);
                _2D.Begin();

                if (_radius > 3.0f)
                {
                    _2D.DrawFilledEllipse(penPosition, Color.Black);
                }
                else
                {
                    _2D.DrawFilledRectangle(penPosition, Color.Black);
                }
                _2D.End();
                _graphics.SetRenderTarget(_screen.RenderTargetView);
            }

            _2D.Begin();
            _2D.DrawTextSprite(_messageSprite);
            _2D.End();

            _screen.Present(1);

            return(true);
        }
Example #21
0
        /// <summary>
        /// Function to draw the pretty picture.
        /// </summary>
        private void DrawAPrettyPicture()
        {
            // Paint color.
            Color paintColor;

            // Clear the back buffer.
            _screen.RenderTargetView.Clear(Color.FromArgb(0, 0, 64));

            // First, we need to inform the renderer that we're about draw some stuff.
            _renderer.Begin();

            // Draw some points as stars.
            for (int x = 0; x < 1000; x++)
            {
                // Color.
                int colorSwitch = GorgonRandom.RandomInt32(160) + 95;   // Color component for the points.

                // Get the star color.
                paintColor = Color.FromArgb(colorSwitch, colorSwitch, colorSwitch);

                _renderer.DrawFilledRectangle(new DX.RectangleF(GorgonRandom.RandomSingle(_screen.Width), GorgonRandom.RandomSingle(_screen.Height), 1, 1), paintColor);
            }

            // Draw lines.
            for (int x = 0; x < 360; x++)
            {
                float cos = (x + (x / 2.0f)).FastCos();     // Cosine.
                float sin = (x + (x / 3.0f)).FastSin();     // Sin.

                // Set up a random color.
                paintColor = Color.FromArgb((byte)GorgonRandom.RandomInt32(128, 255), GorgonRandom.RandomInt32(64, 255), GorgonRandom.RandomInt32(64, 255), 0);
                var startPosition = new DX.Vector2(sin + _halfSize.Width, cos + _halfSize.Height);
                var endPosition   = new DX.Vector2((cos * (GorgonRandom.RandomSingle(_halfSize.Width * 0.82f))) + startPosition.X, (sin * (GorgonRandom.RandomSingle(_halfSize.Height * 0.82f))) + startPosition.Y);
                _renderer.DrawLine(startPosition.X, startPosition.Y, endPosition.X, endPosition.Y, paintColor);
                //Gorgon.Screen.Line(sin + _halfWidth, cos + _halfHeight, cos * (RandomValue * _halfWidth), sin * (RandomValue * _halfHeight), paintColor);
            }

            // Draw a filled circle.
            float size = (_halfSize.Width / 2.0f) + (GorgonRandom.RandomInt32(10) - 8);
            float half = size / 2.0f;

            _renderer.DrawFilledEllipse(new DX.RectangleF(_halfSize.Width - half, _halfSize.Height - half, size, size), Color.Yellow);

            // Draw some circles in the filled circle (sunspots).
            for (int x = 0; x < 25; x++)
            {
                float radius       = GorgonRandom.RandomSingle(5.0f);
                var   spotPosition = new DX.Vector2((GorgonRandom.RandomSingle((_halfSize.Height / 2.0f)) + _halfSize.Width - (_halfSize.Height / 4.0f)),
                                                    (GorgonRandom.RandomSingle((_halfSize.Height / 2.0f)) + _halfSize.Height - (_halfSize.Height / 4.0f)));
                _renderer.DrawEllipse(new DX.RectangleF(spotPosition.X - (radius * 0.5f),
                                                        spotPosition.Y - (radius * 0.5f),
                                                        radius,
                                                        radius),
                                      Color.Black);
            }

            // Draw some black bars.
            _renderer.DrawFilledRectangle(new DX.RectangleF(0, 0, _screen.Width, _screen.Height / 6.0f), Color.Black);
            _renderer.DrawFilledRectangle(new DX.RectangleF(0, _screen.Height - (_screen.Height / 6.0f), _screen.Width, _screen.Height / 6.0f), Color.Black);

            // Tell the renderer that we're done drawing so we can actually render the shapes.
            _renderer.End();

            GorgonExample.DrawStatsAndLogo(_renderer);

            // Always call this when done or you won't see anything.
            _screen.Present(1);
        }
Example #22
0
        /// <summary>
        /// Function called during idle time the application.
        /// </summary>
        /// <returns><b>true</b> to continue executing, <b>false</b> to stop.</returns>
        private static bool Idle()
        {
            GorgonFont currentFont = _font[_fontIndex];

            if (_startTime < 0)
            {
                _startTime = GorgonTiming.SecondsSinceStart;
            }

            _screen.RenderTargetView.Clear(_glowIndex != _fontIndex ? GorgonColor.CornFlowerBlue : new GorgonColor(0, 0, 0.2f));

            DX.Size2F textSize = currentFont.MeasureText(Resources.Lorem_Ipsum, false);
            var       position = new DX.Vector2((int)((_screen.Width / 2.0f) - (textSize.Width / 2.0f)).Max(4.0f), (int)((_screen.Height / 2.0f) - (textSize.Height / 2.0f)).Max(100));

            _text.Font     = currentFont;
            _text.Position = position;

            // If we have glow on, then draw the glow outline in a separate pass.
            if (_glowIndex == _fontIndex)
            {
                _text.OutlineTint = new GorgonColor(1, 1, 1, _glowAlpha);
                _text.DrawMode    = TextDrawMode.OutlineOnly;
                _renderer.Begin(Gorgon2DBatchState.AdditiveBlend);
                _renderer.DrawTextSprite(_text);
                _renderer.End();
            }

            _text.OutlineTint = GorgonColor.White;
            _text.Color       = _glowIndex != _fontIndex ? GorgonColor.White : GorgonColor.Black;
            _text.DrawMode    = ((_glowIndex == _fontIndex) || (!currentFont.HasOutline)) ? TextDrawMode.GlyphsOnly : TextDrawMode.OutlinedGlyphs;

            // Draw the font identification.
            _renderer.Begin();
            _renderer.DrawString($"Now displaying [c #FFFFE03F]'{currentFont.Name}'[/c]...", new DX.Vector2(4.0f, 64.0f));
            _renderer.DrawTextSprite(_text);
            _renderer.End();

            GorgonExample.DrawStatsAndLogo(_renderer);

            // Animate our glow alpha.
            _glowAlpha += _glowVelocity * GorgonTiming.Delta;

            if (_glowAlpha > 1.0f)
            {
                _glowAlpha    = 1.0f;
                _glowVelocity = -0.5f;
            }
            else if (_glowAlpha < 0.25f)
            {
                _glowAlpha    = 0.25f;
                _glowVelocity = 0.5f;
            }

            // Animate the line height so we can drop the lines and make them bounce... just because we can.
            float normalSin = (_bounceAngle.ToRadians().Sin() + 1.0f) / 2.0f;
            float scaledSin = normalSin * (1.0f - _max);

            _text.LineSpace = scaledSin + _max;

            _bounceAngle += _angleSpeed * GorgonTiming.Delta;

            if (_bounceAngle > 90.0f)
            {
                _bounceAngle = 90.0f;
                if (_max.EqualsEpsilon(0))
                {
                    _max = 0.5f;
                }
                else
                {
                    _max += 0.125f;
                }

                if (_max >= 1.0f)
                {
                    _max = 1.0f;
                }
                _angleSpeed = -_angleSpeed * (_max + 1.0f);
            }

            if (_bounceAngle < -90.0f)
            {
                _angleSpeed  = -_angleSpeed;
                _bounceAngle = -90.0f;
            }

            int timeDiff = (int)(GorgonTiming.SecondsSinceStart - _startTime).FastCeiling();

            // Switch to a new font every 4 seconds.
            if (timeDiff > 4)
            {
                _startTime = GorgonTiming.SecondsSinceStart;
                ++_fontIndex;
                _text.LineSpace = -0.015f;

                // Reset glow animation.
                if (_fontIndex == _glowIndex)
                {
                    _glowAlpha    = 1.0f;
                    _glowVelocity = -0.5f;
                }

                // Reset bounce.
                _bounceAngle = -90.0f;
                _max         = 0.0f;
                _angleSpeed  = 360.0f;
            }


            if (_fontIndex >= _font.Count)
            {
                _fontIndex = 0;
            }

            _screen.Present(1);

            return(true);
        }