Exemplo n.º 1
0
        private IEnumerable <Drawable> buildPositionalInputQueue(InputState state)
        {
            positionalInputQueue.Clear();

            if (this is UserInputManager)
            {
                FrameStatistics.Increment(StatisticsCounterType.PositionalIQ);
            }

            var children = AliveInternalChildren;

            for (int i = 0; i < children.Count; i++)
            {
                children[i].BuildPositionalInputQueue(state.Mouse.Position, positionalInputQueue);
            }

            positionalInputQueue.Reverse();
            return(positionalInputQueue);
        }
Exemplo n.º 2
0
        private void handleKeyboardEvent(object sender, KeyboardKeyEventArgs e)
        {
            var rawState = e.Keyboard;

            if (lastRawState != null && rawState.Equals(lastRawState))
            {
                return;
            }

            lastRawState = rawState;

            var newState = new TkKeyboardState(rawState);

            PendingInputs.Enqueue(new KeyboardKeyInput(newState.Keys, lastEventState?.Keys));

            lastEventState = newState;

            FrameStatistics.Increment(StatisticsCounterType.KeyEvents);
        }
Exemplo n.º 3
0
        public override bool Initialize(GameHost host)
        {
            Enabled.BindValueChanged(enabled =>
            {
                if (enabled)
                {
                    host.InputThread.Scheduler.Add(scheduledRefreshDevices = new ScheduledDelegate(refreshDevices, 0, 500));

                    host.InputThread.Scheduler.Add(scheduledPoll = new ScheduledDelegate(delegate
                    {
                        foreach (var device in devices)
                        {
                            if (device.RawState.Equals(device.LastRawState))
                            {
                                continue;
                            }

                            var newState = new OpenTKJoystickState(device);
                            handleState(device, newState);
                            FrameStatistics.Increment(StatisticsCounterType.JoystickEvents);
                        }
                    }, 0, 0));
                }
                else
                {
                    scheduledPoll?.Cancel();
                    scheduledRefreshDevices?.Cancel();

                    foreach (var device in devices)
                    {
                        if (device.LastState != null)
                        {
                            handleState(device, new JoystickState());
                        }
                    }

                    devices.Clear();
                    mostSeenDevices = 0;
                }
            }, true);

            return(true);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Refresh using a cached delegate.
        /// </summary>
        /// <returns>Whether refreshing was possible.</returns>
        public bool EnsureValid()
        {
            if (IsValid)
            {
                return(true);
            }

            if (updateDelegate == null)
            {
                return(false);
            }

            value   = updateDelegate();
            isValid = true;

            FrameStatistics.Increment(StatisticsCounterType.Refreshes);

            return(true);
        }
Exemplo n.º 5
0
        private SlimReadOnlyListWrapper <Drawable> buildPositionalInputQueue(Vector2 screenSpacePos)
        {
            positionalInputQueue.Clear();

            if (this is UserInputManager)
            {
                FrameStatistics.Increment(StatisticsCounterType.PositionalIQ);
            }

            var children = AliveInternalChildren;

            for (int i = 0; i < children.Count; i++)
            {
                children[i].BuildPositionalInputQueue(screenSpacePos, positionalInputQueue);
            }

            positionalInputQueue.Reverse();
            return(positionalInputQueue.AsSlimReadOnly());
        }
Exemplo n.º 6
0
        protected override void LoadComplete()
        {
            base.LoadComplete();

            PerformanceOverlay performanceOverlay;

            LoadComponentAsync(performanceOverlay = new PerformanceOverlay(Host.Threads.Reverse())
            {
                Margin       = new MarginPadding(5),
                Direction    = FillDirection.Vertical,
                Spacing      = new Vector2(10, 10),
                AutoSizeAxes = Axes.Both,
                Alpha        = 0,
                Anchor       = Anchor.BottomRight,
                Origin       = Anchor.BottomRight,
                Depth        = float.MinValue
            }, AddInternal);

            FrameStatistics.BindValueChanged(e => performanceOverlay.State = e.NewValue, true);
        }
Exemplo n.º 7
0
        /// <summary>
        /// Binds a texture to draw with.
        /// </summary>
        /// <param name="textureId">The texture to bind.</param>
        /// <param name="unit">The texture unit to bind it to.</param>
        /// <returns>true if the provided texture was not already bound (causing a binding change).</returns>
        public static bool BindTexture(int textureId, TextureUnit unit = TextureUnit.Texture0)
        {
            var index = GetTextureUnitId(unit);

            if (last_bound_texture[index] == textureId)
            {
                return(false);
            }

            FlushCurrentBatch();

            GL.ActiveTexture(unit);
            GL.BindTexture(TextureTarget.Texture2D, textureId);

            last_bound_texture[index] = textureId;
            last_bound_texture_is_atlas[GetTextureUnitId(unit)] = false;

            FrameStatistics.Increment(StatisticsCounterType.TextureBinds);
            return(true);
        }
Exemplo n.º 8
0
        private void dispatchEvent(byte eventType, byte key, byte velocity)
        {
            Logger.Log($"Handling MIDI event {eventType:X2}:{key:X2}:{velocity:X2}");

            switch (eventType)
            {
            case MidiEvent.NoteOn when velocity != 0:
                Logger.Log($"NoteOn: {(MidiKey)key}/{velocity / 128f:P}");
                PendingInputs.Enqueue(new MidiKeyInput((MidiKey)key, velocity, true));
                FrameStatistics.Increment(StatisticsCounterType.MidiEvents);
                break;

            case MidiEvent.NoteOff:
            case MidiEvent.NoteOn when velocity == 0:
                Logger.Log($"NoteOff: {(MidiKey)key}/{velocity / 128f:P}");
                PendingInputs.Enqueue(new MidiKeyInput((MidiKey)key, 0, false));
                FrameStatistics.Increment(StatisticsCounterType.MidiEvents);
                break;
            }
        }
Exemplo n.º 9
0
        public override void DrawTriangle(Triangle vertexTriangle, RectangleF?textureRect, ColourInfo drawColour, Action <TexturedVertex2D> vertexAction = null, Vector2?inflationPercentage = null)
        {
            Debug.Assert(!isDisposed);

            RectangleF texRect = GetTextureRect(textureRect);

            if (inflationPercentage.HasValue)
            {
                texRect = texRect.Inflate(new Vector2(inflationPercentage.Value.X * texRect.Width, inflationPercentage.Value.Y * texRect.Height));
            }

            if (vertexAction == null)
            {
                if (triangleBatch == null)
                {
                    triangleBatch = new LinearBatch <TexturedVertex2D>(512, 128, PrimitiveType.Triangles);
                }
                vertexAction = triangleBatch.Add;
            }

            vertexAction(new TexturedVertex2D
            {
                Position        = vertexTriangle.P0,
                TexturePosition = new Vector2((texRect.Left + texRect.Right) / 2, texRect.Top),
                Colour          = drawColour.TopLeft.Linear,
            });
            vertexAction(new TexturedVertex2D
            {
                Position        = vertexTriangle.P1,
                TexturePosition = new Vector2(texRect.Left, texRect.Bottom),
                Colour          = drawColour.BottomLeft.Linear,
            });
            vertexAction(new TexturedVertex2D
            {
                Position        = vertexTriangle.P2,
                TexturePosition = new Vector2(texRect.Right, texRect.Bottom),
                Colour          = drawColour.BottomRight.Linear,
            });

            FrameStatistics.Increment(StatisticsCounterType.KiloPixels, (long)vertexTriangle.ConservativeArea);
        }
Exemplo n.º 10
0
        public override bool Initialize(GameHost host)
        {
            Enabled.BindValueChanged(e =>
            {
                if (e.NewValue)
                {
                    host.InputThread.Scheduler.Add(scheduled = new ScheduledDelegate(delegate
                    {
                        refreshDevices();

                        foreach (var device in devices)
                        {
                            if ((device.LastRawState.HasValue && device.RawState.Equals(device.LastRawState.Value)) ||
                                !device.RawState.IsConnected)
                            {
                                continue;
                            }

                            handleState(device, new OsuTKJoystickState(device));
                            FrameStatistics.Increment(StatisticsCounterType.JoystickEvents);
                        }
                    }, 0, 0));
                }
                else
                {
                    scheduled?.Cancel();

                    foreach (var device in devices)
                    {
                        if (device.LastState != null)
                        {
                            handleState(device, new JoystickState());
                        }
                    }

                    devices.Clear();
                }
            }, true);

            return(true);
        }
Exemplo n.º 11
0
        protected BasicGameHost(string gameName = @"")
        {
            Instance = this;

            AppDomain.CurrentDomain.UnhandledException += exceptionHandler;

            Dependencies.Cache(this);
            name = gameName;

            threads = new[]
            {
                DrawThread = new GameThread(DrawFrame, @"Draw")
                {
                    OnThreadStart = DrawInitialize,
                },
                UpdateThread = new GameThread(UpdateFrame, @"Update")
                {
                    OnThreadStart = UpdateInitialize,
                    Monitor       = { HandleGC = true }
                },
                InputThread = new InputThread(null, @"Input") //never gets started.
            };

            Clock = UpdateThread.Clock;

            MaximumUpdateHz = GameThread.DEFAULT_ACTIVE_HZ;
            MaximumDrawHz   = (DisplayDevice.Default?.RefreshRate ?? 0) * 4;

            // Note, that RegisterCounters only has an effect for the first
            // BasicGameHost to be passed into it; i.e. the first BasicGameHost
            // to be instantiated.
            FrameStatistics.RegisterCounters(this);

            Environment.CurrentDirectory = System.IO.Path.GetDirectoryName(FullPath);

            setActive(true);

            AddInternal(inputManager = new UserInputManager(this));

            Dependencies.Cache(inputManager);
        }
Exemplo n.º 12
0
        private int addArea(FrameStatistics frame, PerformanceCollectionType frameTimeType, int currentHeight, byte[] textureData)
        {
            Debug.Assert(textureData.Length >= HEIGHT * 4, $"textureData is too small ({textureData.Length}) to hold area data.");

            double elapsedMilliseconds = 0;
            int    drawHeight          = 0;

            if (frameTimeType == PerformanceCollectionType.Empty)
            {
                drawHeight = currentHeight;
            }
            else if (frame.CollectedTimes.TryGetValue(frameTimeType, out elapsedMilliseconds))
            {
                legendMapping[(int)frameTimeType].Alpha = 1;
                drawHeight = (int)(elapsedMilliseconds * scale);
            }
            else
            {
                return(currentHeight);
            }

            Color4 col = getColour(frameTimeType);

            for (int i = currentHeight - 1; i >= 0; --i)
            {
                if (drawHeight-- == 0)
                {
                    break;
                }

                int index = i * 4;
                textureData[index]     = (byte)(255 * col.R);
                textureData[index + 1] = (byte)(255 * col.G);
                textureData[index + 2] = (byte)(255 * col.B);
                textureData[index + 3] = (byte)(255 * (frameTimeType == PerformanceCollectionType.Empty ? (col.A * (1 - (int)((i * 4) / HEIGHT) / 8f)) : col.A));
                currentHeight--;
            }

            return(currentHeight);
        }
Exemplo n.º 13
0
        private void dispatchEvent(byte eventType, byte key, byte velocity)
        {
            Logger.Log($"Handling MIDI event {eventType:X2}:{key:X2}:{velocity:X2}");

            // Low nibble only contains channel data in note on/off messages
            // Ignore to receive messages from all channels
            switch (eventType & 0xF0)
            {
            case MidiEvent.NoteOn when velocity != 0:
                Logger.Log($"NoteOn: {(MidiKey)key}/{velocity / 128f:P}");
                PendingInputs.Enqueue(new MidiKeyInput((MidiKey)key, velocity, true));
                FrameStatistics.Increment(StatisticsCounterType.MidiEvents);
                break;

            case MidiEvent.NoteOff:
            case MidiEvent.NoteOn when velocity == 0:
                Logger.Log($"NoteOff: {(MidiKey)key}/{velocity / 128f:P}");
                PendingInputs.Enqueue(new MidiKeyInput((MidiKey)key, 0, false));
                FrameStatistics.Increment(StatisticsCounterType.MidiEvents);
                break;
            }
        }
Exemplo n.º 14
0
        public override bool Initialize(GameHost host)
        {
            host.InputThread.Scheduler.Add(scheduled = new ScheduledDelegate(delegate
            {
                var state = host.IsActive ? OpenTK.Input.Keyboard.GetState() : new OpenTK.Input.KeyboardState();

                if (state.Equals(lastState))
                {
                    return;
                }

                lastState = state;

                PendingStates.Enqueue(new InputState {
                    Keyboard = new TkKeyboardState(state)
                });

                FrameStatistics.Increment(StatisticsCounterType.KeyEvents);
            }, 0, 0));

            return(true);
        }
        protected void HandleState(OsuTKMouseState state, OsuTKMouseState lastState, bool isAbsolutePosition)
        {
            if (lastState == null || isAbsolutePosition)
            {
                PendingInputs.Enqueue(new MousePositionAbsoluteInput {
                    Position = state.Position
                });
                currentPosition = state.Position;
            }
            else
            {
                var delta = state.Position - lastState.Position;

                if (delta != Vector2.Zero)
                {
                    PendingInputs.Enqueue(new MousePositionRelativeInput {
                        Delta = delta
                    });
                    currentPosition += delta;
                }
            }

            if (lastState != null && state.WasActive)
            {
                var scrollDelta = state.Scroll - lastState.Scroll;

                if (scrollDelta != Vector2.Zero)
                {
                    PendingInputs.Enqueue(new MouseScrollRelativeInput {
                        Delta = scrollDelta, IsPrecise = state.HasPreciseScroll
                    });
                }
            }

            PendingInputs.Enqueue(new MouseButtonInput(state.Buttons, lastState?.Buttons));

            FrameStatistics.Increment(StatisticsCounterType.MouseEvents);
        }
Exemplo n.º 16
0
        /// <param name="instanceCount">if >0 will draw instanced geometry</param>
        /// <returns></returns>
        public int DrawInstanced(int instanceCount)
        {
            if (currentVertex == lastVertex)
            {
                return(0);
            }

            VertexBuffer <T> vertexBuffer = CurrentVertexBuffer;

            if (changeBeginIndex >= 0)
            {
                vertexBuffer.UpdateRange(changeBeginIndex, changeEndIndex);
            }

            if (instanceCount > 0)
            {
                vertexBuffer.DrawRangeInstanced(lastVertex, currentVertex, instanceCount);
            }
            else
            {
                vertexBuffer.DrawRange(lastVertex, currentVertex);
            }

            int count = currentVertex - lastVertex;

            // When using multiple buffers we advance to the next one with every draw to prevent contention on the same buffer with future vertex updates.
            //TODO: let us know if we exceed and roll over to zero here.
            currentVertexBuffer = (currentVertexBuffer + 1) % maxBuffers;
            currentVertex       = 0;

            lastVertex       = currentVertex;
            changeBeginIndex = -1;

            FrameStatistics.Increment(StatisticsCounterType.DrawCalls);
            FrameStatistics.Increment(StatisticsCounterType.VerticesDraw, count);

            return(count);
        }
Exemplo n.º 17
0
        public override bool Initialize(GameHost host)
        {
            Enabled.ValueChanged += enabled =>
            {
                if (enabled)
                {
                    host.InputThread.Scheduler.Add(scheduled = new ScheduledDelegate(delegate
                    {
                        refreshDevices();

                        foreach (var device in devices)
                        {
                            if (device.State.Equals(device.LastState))
                            {
                                continue;
                            }

                            if (device.LastState != null)
                            {
                                PendingStates.Enqueue(new InputState {
                                    Joystick = new OpenTKJoystickState(device)
                                });
                                FrameStatistics.Increment(StatisticsCounterType.JoystickEvents);
                            }
                        }
                    }, 0, 0));
                }
                else
                {
                    scheduled?.Cancel();
                    devices.Clear();
                }
            };

            Enabled.TriggerChange();

            return(true);
        }
Exemplo n.º 18
0
        /// <summary>
        /// Generates the DrawNode for ourselves.
        /// </summary>
        /// <returns>A complete and updated DrawNode, or null if the DrawNode would be invisible.</returns>
        protected internal virtual DrawNode GenerateDrawNodeSubtree(int treeIndex, RectangleF bounds)
        {
            if (isProxied)
            {
                return(null);
            }

            DrawNode node = drawNodes[treeIndex];

            if (node == null)
            {
                drawNodes[treeIndex] = node = CreateDrawNode();
                FrameStatistics.Increment(StatisticsCounterType.DrawNodeCtor);
            }

            if (invalidationID != node.InvalidationID)
            {
                ApplyDrawNode(node);
                FrameStatistics.Increment(StatisticsCounterType.DrawNodeAppl);
            }

            return(node);
        }
Exemplo n.º 19
0
        public override bool Initialize(GameHost host)
        {
            host.InputThread.Scheduler.Add(scheduled = new ScheduledDelegate(delegate
            {
                OpenTK.Input.MouseState state = OpenTK.Input.Mouse.GetCursorState();
                Point point = host.Window.PointToClient(new Point(state.X, state.Y));

                //todo: reimplement if necessary
                //Vector2 pos = Vector2.Multiply(point, Vector2.Divide(host.DrawSize, this.Size));

                Vector2 pos = new Vector2(point.X, point.Y);

                var tkState = new TkMouseState(state, pos, host.IsActive);

                PendingStates.Enqueue(new InputState {
                    Mouse = tkState
                });

                FrameStatistics.Increment(StatisticsCounterType.MouseEvents);
            }, 0, 0));

            return(true);
        }
Exemplo n.º 20
0
        /// <summary>
        /// Updates this audio component. Always runs on the audio thread.
        /// </summary>
        public void Update()
        {
            ThreadSafety.EnsureNotUpdateThread();
            if (IsDisposed)
            {
                throw new ObjectDisposedException(ToString(), "Can not update disposed audio components.");
            }

            FrameStatistics.Add(StatisticsCounterType.TasksRun, PendingActions.Count);
            FrameStatistics.Increment(StatisticsCounterType.Components);

            Action action;

            while (!IsDisposed && PendingActions.TryDequeue(out action))
            {
                action();
            }

            if (!IsDisposed)
            {
                UpdateState();
            }
        }
Exemplo n.º 21
0
        /// <summary>
        /// Updates this Drawable and all Drawables further down the scene graph.
        /// Called once every frame.
        /// </summary>
        /// <returns>False if the drawable should not be updated.</returns>
        protected internal virtual bool UpdateSubTree()
        {
            Debug.Assert(!isDisposed, "Disposed Drawables may never be in the scene graph.");

            if (Parent != null) //we don't want to update our clock if we are at the top of the stack. it's handled elsewhere for us.
            {
                customClock?.ProcessFrame();
            }

            if (LoadState < LoadState.Alive)
            {
                if (!loadComplete())
                {
                    return(false);
                }
            }

            transformationDelay = 0;

            //todo: this should be moved to after the IsVisible condition once we have TOL for transformations (and some better logic).
            updateTransforms();

            if (!IsPresent)
            {
                return(true);
            }

            if (scheduler != null)
            {
                int amountScheduledTasks = scheduler.Update();
                FrameStatistics.Increment(StatisticsCounterType.ScheduleInvk, amountScheduledTasks);
            }

            Update();
            OnUpdate?.Invoke();
            return(true);
        }
        public sealed override void Draw(Action <TexturedVertex2D> vertexAction)
        {
            if (RequiresRedraw)
            {
                FrameStatistics.Increment(StatisticsCounterType.FBORedraw);

                SharedData.ResetCurrentEffectBuffer();

                using (establishFrameBufferViewport())
                {
                    // Fill the frame buffer with drawn children
                    using (BindFrameBuffer(SharedData.MainBuffer))
                    {
                        // We need to draw children as if they were zero-based to the top-left of the texture.
                        // We can do this by adding a translation component to our (orthogonal) projection matrix.
                        GLWrapper.PushOrtho(screenSpaceDrawRectangle);
                        GLWrapper.Clear(new ClearInfo(backgroundColour));

                        Child.Draw(vertexAction);

                        GLWrapper.PopOrtho();
                    }

                    PopulateContents();
                }

                SharedData.DrawVersion = GetDrawVersion();
            }

            Shader.Bind();

            base.Draw(vertexAction);
            DrawContents();

            Shader.Unbind();
        }
Exemplo n.º 23
0
        public override bool Initialize(GameHost host)
        {
            host.InputThread.Scheduler.Add(scheduled = new ScheduledDelegate(delegate
            {
                if (!host.Window.Visible)
                {
                    return;
                }

                var state = OpenTK.Input.Mouse.GetCursorState();

                if (state.Equals(lastState))
                {
                    return;
                }

                lastState = state;

                Point point = host.Window.PointToClient(new Point(state.X, state.Y));
                Vector2 pos = new Vector2(point.X, point.Y);

                // While not focused, let's silently ignore everything but position.
                if (!host.Window.Focused)
                {
                    state = new OpenTK.Input.MouseState();
                }

                PendingStates.Enqueue(new InputState {
                    Mouse = new TkMouseState(state, pos, host.IsActive)
                });

                FrameStatistics.Increment(StatisticsCounterType.MouseEvents);
            }, 0, 0));

            return(true);
        }
Exemplo n.º 24
0
 protected override void UpdateState()
 {
     FrameStatistics.Increment(StatisticsCounterType.SChannels);
     base.UpdateState();
 }
Exemplo n.º 25
0
 public void Begin()
 {
     start = Time.realtimeSinceStartup;
     frameStats = GetComponent<FrameStatistics>();
     frameStats.Initialize();
 }
Exemplo n.º 26
0
 protected override void UpdateState()
 {
     FrameStatistics.Add(StatisticsCounterType.Samples, factories.Count);
     base.UpdateState();
 }
Exemplo n.º 27
0
        protected override bool CheckChildrenLife()
        {
            // We have to at least wait until Clock becomes available.
            if (LoadState != LoadState.Loaded)
            {
                return(false);
            }

            bool aliveChildrenChanged = false;

            // Move loaded children to appropriate list.
            for (var i = newChildren.Count - 1; i >= 0; --i)
            {
                FrameStatistics.Increment(StatisticsCounterType.CCL);
                var child = newChildren[i];

                if (child.LoadState >= LoadState.Ready)
                {
                    Debug.Assert(!childStateMap.ContainsKey(child));

                    newChildren.RemoveAt(i);

                    var entry = new ChildEntry(child);
                    childStateMap.Add(child, entry);

                    aliveChildrenChanged |= updateChildEntry(entry);
                }
            }

            var currentTime = Time.Current;

            // Checks for newly alive children when time is increased or new children added.
            while (futureChildren.Count > 0)
            {
                FrameStatistics.Increment(StatisticsCounterType.CCL);
                var entry = futureChildren.Min;
                Debug.Assert(entry.State == LifetimeState.Future);

                if (currentTime < entry.LifetimeStart)
                {
                    break;
                }

                futureChildren.Remove(entry);

                aliveChildrenChanged |= updateChildEntry(entry);
            }

            while (pastChildren.Count > 0)
            {
                FrameStatistics.Increment(StatisticsCounterType.CCL);
                var entry = pastChildren.Max;
                Debug.Assert(entry.State == LifetimeState.Past);

                if (entry.LifetimeEnd <= currentTime)
                {
                    break;
                }

                pastChildren.Remove(entry);

                aliveChildrenChanged |= updateChildEntry(entry);
            }

            for (var i = AliveInternalChildren.Count - 1; i >= 0; --i)
            {
                FrameStatistics.Increment(StatisticsCounterType.CCL);
                var child = AliveInternalChildren[i];
                Debug.Assert(childStateMap.ContainsKey(child));
                var entry = childStateMap[child];

                aliveChildrenChanged |= updateChildEntry(entry);
            }

            Debug.Assert(newChildren.Count + futureChildren.Count + pastChildren.Count + AliveInternalChildren.Count == InternalChildren.Count);

            while (eventQueue.Count != 0)
            {
                var e = eventQueue.Dequeue();
                OnChildLifetimeBoundaryCrossed(e);
            }

            return(aliveChildrenChanged);
        }
Exemplo n.º 28
0
        public override void DrawTriangle(Triangle vertexTriangle, RectangleF?textureRect, ColourInfo drawColour, Action <TexturedVertex2D> vertexAction = null, Vector2?inflationPercentage = null)
        {
            if (IsDisposed)
            {
                throw new ObjectDisposedException(ToString(), "Can not draw a triangle with a disposed texture.");
            }

            RectangleF texRect         = GetTextureRect(textureRect);
            Vector2    inflationAmount = inflationPercentage.HasValue ? new Vector2(inflationPercentage.Value.X * texRect.Width, inflationPercentage.Value.Y * texRect.Height) : Vector2.Zero;
            RectangleF inflatedTexRect = texRect.Inflate(inflationAmount);

            if (vertexAction == null)
            {
                vertexAction = default_triangle_action;
            }

            // We split the triangle into two, such that we can obtain smooth edges with our
            // texture coordinate trick. We might want to revert this to drawing a single
            // triangle in case we ever need proper texturing, or if the additional vertices
            // end up becoming an overhead (unlikely).
            SRGBColour topColour    = (drawColour.TopLeft + drawColour.TopRight) / 2;
            SRGBColour bottomColour = (drawColour.BottomLeft + drawColour.BottomRight) / 2;

            // Left triangle half
            vertexAction(new TexturedVertex2D
            {
                Position        = vertexTriangle.P0,
                TexturePosition = new Vector2(inflatedTexRect.Left, inflatedTexRect.Top),
                TextureRect     = new Vector4(texRect.Left, texRect.Top, texRect.Right, texRect.Bottom),
                BlendRange      = inflationAmount,
                Colour          = topColour.Linear,
            });
            vertexAction(new TexturedVertex2D
            {
                Position        = vertexTriangle.P1,
                TexturePosition = new Vector2(inflatedTexRect.Left, inflatedTexRect.Bottom),
                TextureRect     = new Vector4(texRect.Left, texRect.Top, texRect.Right, texRect.Bottom),
                BlendRange      = inflationAmount,
                Colour          = drawColour.BottomLeft.Linear,
            });
            vertexAction(new TexturedVertex2D
            {
                Position        = (vertexTriangle.P1 + vertexTriangle.P2) / 2,
                TexturePosition = new Vector2((inflatedTexRect.Left + inflatedTexRect.Right) / 2, inflatedTexRect.Bottom),
                TextureRect     = new Vector4(texRect.Left, texRect.Top, texRect.Right, texRect.Bottom),
                BlendRange      = inflationAmount,
                Colour          = bottomColour.Linear,
            });

            // Right triangle half
            vertexAction(new TexturedVertex2D
            {
                Position        = vertexTriangle.P0,
                TexturePosition = new Vector2(inflatedTexRect.Right, inflatedTexRect.Top),
                TextureRect     = new Vector4(texRect.Left, texRect.Top, texRect.Right, texRect.Bottom),
                BlendRange      = inflationAmount,
                Colour          = topColour.Linear,
            });
            vertexAction(new TexturedVertex2D
            {
                Position        = (vertexTriangle.P1 + vertexTriangle.P2) / 2,
                TexturePosition = new Vector2((inflatedTexRect.Left + inflatedTexRect.Right) / 2, inflatedTexRect.Bottom),
                TextureRect     = new Vector4(texRect.Left, texRect.Top, texRect.Right, texRect.Bottom),
                BlendRange      = inflationAmount,
                Colour          = bottomColour.Linear,
            });
            vertexAction(new TexturedVertex2D
            {
                Position        = vertexTriangle.P2,
                TexturePosition = new Vector2(inflatedTexRect.Right, inflatedTexRect.Bottom),
                TextureRect     = new Vector4(texRect.Left, texRect.Top, texRect.Right, texRect.Bottom),
                BlendRange      = inflationAmount,
                Colour          = drawColour.BottomRight.Linear,
            });

            FrameStatistics.Add(StatisticsCounterType.Pixels, (long)vertexTriangle.ConservativeArea);
        }
Exemplo n.º 29
0
 private void enqueueJoystickEvent(IInput evt)
 {
     PendingInputs.Enqueue(evt);
     FrameStatistics.Increment(StatisticsCounterType.JoystickEvents);
 }
Exemplo n.º 30
0
 private void enqueueInput(IInput input)
 {
     PendingInputs.Enqueue(input);
     FrameStatistics.Increment(StatisticsCounterType.KeyEvents);
 }
Exemplo n.º 31
0
 protected override void UpdateState()
 {
     FrameStatistics.Add(StatisticsCounterType.Samples, sampleCache.Count);
     base.UpdateState();
 }