예제 #1
0
        private void handleState(MouseState state)
        {
            // combine scroll values to avoid discrepancy between sources.
            state        = (MouseState)state.Clone();
            state.Scroll = (lastEventState?.Scroll ?? Vector2.Zero) + (lastPollState?.Scroll ?? Vector2.Zero);

            PendingStates.Enqueue(new InputState {
                Mouse = state
            });
            FrameStatistics.Increment(StatisticsCounterType.MouseEvents);
        }
예제 #2
0
        protected override void UpdateState()
        {
            FrameStatistics.Increment(StatisticsCounterType.Tracks);

            if (Looping && HasReachedEnd)
            {
                Restart();
            }

            base.UpdateState();
        }
예제 #3
0
        /// <summary>
        /// Invalidate the cache of this object.
        /// </summary>
        /// <returns>True if we invalidated from a valid state.</returns>
        public bool Invalidate()
        {
            if (IsValid)
            {
                IsValid = false;
                FrameStatistics.Increment(StatisticsCounterType.Invalidations);
                return(true);
            }

            return(false);
        }
예제 #4
0
        public override void Update()
        {
            FrameStatistics.Increment(StatisticsCounterType.Tracks);

            base.Update();
            if (Looping && !IsRunning && Length == CurrentTime)
            {
                Reset();
                Start();
            }
        }
예제 #5
0
        protected void Validate()
        {
            if (IsValid)
            {
                return;
            }

            IsValid = true;
            Parent?.ValidateSuperTree(Invalidation);
            FrameStatistics.Increment(StatisticsCounterType.Refreshes);
        }
예제 #6
0
        public void UpdateRange(int startIndex, int endIndex)
        {
            Bind(false);

            int amountVertices = endIndex - startIndex;

            GL.BufferSubData(BufferTarget.ArrayBuffer, (IntPtr)(startIndex * stride), (IntPtr)(amountVertices * stride), ref Vertices[startIndex]);

            Unbind();

            FrameStatistics.Increment(StatisticsCounterType.VerticesUpl, amountVertices);
        }
예제 #7
0
        public override void Update()
        {
            FrameStatistics.Increment(StatisticsCounterType.Tracks);

            if (Looping && HasCompleted)
            {
                Reset();
                Start();
            }

            base.Update();
        }
예제 #8
0
        /// <summary>
        /// Binds a texture to darw with.
        /// </summary>
        /// <param name="texture"></param>
        public static void BindTexture(TextureGL texture)
        {
            if (lastBoundTexture != texture)
            {
                FlushCurrentBatch();

                GL.BindTexture(TextureTarget.Texture2D, texture?.TextureId ?? 0);
                lastBoundTexture = texture;

                FrameStatistics.Increment(StatisticsCounterType.TextureBinds);
            }
        }
예제 #9
0
        public override void DrawQuad(Quad vertexQuad, RectangleF?textureRect, ColourInfo drawColour, Action <TexturedVertex2D> vertexAction = null, Vector2?inflationPercentage = null)
        {
            Debug.Assert(!IsDisposed);

            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)
            {
                if (quadBatch == null)
                {
                    quadBatch = new QuadBatch <TexturedVertex2D>(512, 128);
                }
                vertexAction = quadBatch.Add;
            }

            vertexAction(new TexturedVertex2D
            {
                Position        = vertexQuad.BottomLeft,
                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        = vertexQuad.BottomRight,
                TexturePosition = new Vector2(inflatedTexRect.Right, inflatedTexRect.Bottom),
                TextureRect     = new Vector4(texRect.Left, texRect.Top, texRect.Right, texRect.Bottom),
                BlendRange      = inflationAmount,
                Colour          = drawColour.BottomRight.Linear,
            });
            vertexAction(new TexturedVertex2D
            {
                Position        = vertexQuad.TopRight,
                TexturePosition = new Vector2(inflatedTexRect.Right, inflatedTexRect.Top),
                TextureRect     = new Vector4(texRect.Left, texRect.Top, texRect.Right, texRect.Bottom),
                BlendRange      = inflationAmount,
                Colour          = drawColour.TopRight.Linear,
            });
            vertexAction(new TexturedVertex2D
            {
                Position        = vertexQuad.TopLeft,
                TexturePosition = new Vector2(inflatedTexRect.Left, inflatedTexRect.Top),
                TextureRect     = new Vector4(texRect.Left, texRect.Top, texRect.Right, texRect.Bottom),
                BlendRange      = inflationAmount,
                Colour          = drawColour.TopLeft.Linear,
            });

            FrameStatistics.Increment(StatisticsCounterType.KiloPixels, (long)vertexQuad.ConservativeArea);
        }
예제 #10
0
        public override bool Initialize(GameHost host)
        {
            host.InputThread.Scheduler.Add(scheduled = new ScheduledDelegate(delegate
            {
                PendingStates.Enqueue(new InputState
                {
                    Keyboard = new TkKeyboardState(host.IsActive ? OpenTK.Input.Keyboard.GetState() : new OpenTK.Input.KeyboardState())
                });

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

            return(true);
        }
예제 #11
0
        /// <summary>
        /// Blits sprite to OpenGL display with specified parameters.
        /// </summary>
        public override void Draw(Quad vertexQuad, RectangleF?textureRect, Color4 drawColour, VertexBatch <TexturedVertex2D> spriteBatch = 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 (spriteBatch == null)
            {
                if (TextureGLSingle.spriteBatch == null)
                {
                    TextureGLSingle.spriteBatch = new QuadBatch <TexturedVertex2D>(512, 128);
                }
                spriteBatch = TextureGLSingle.spriteBatch;
            }

            Color4 linearColour = drawColour.toLinear();

            spriteBatch.Add(new TexturedVertex2D
            {
                Position        = vertexQuad.BottomLeft,
                TexturePosition = new Vector2(texRect.Left, texRect.Bottom),
                Colour          = linearColour
            });
            spriteBatch.Add(new TexturedVertex2D
            {
                Position        = vertexQuad.BottomRight,
                TexturePosition = new Vector2(texRect.Right, texRect.Bottom),
                Colour          = linearColour
            });
            spriteBatch.Add(new TexturedVertex2D
            {
                Position        = vertexQuad.TopRight,
                TexturePosition = new Vector2(texRect.Right, texRect.Top),
                Colour          = linearColour
            });
            spriteBatch.Add(new TexturedVertex2D
            {
                Position        = vertexQuad.TopLeft,
                TexturePosition = new Vector2(texRect.Left, texRect.Top),
                Colour          = linearColour
            });

            FrameStatistics.Increment(StatisticsCounterType.KiloPixels, (long)vertexQuad.ConservativeArea);
        }
예제 #12
0
        /// <summary>
        /// Binds a texture to darw with.
        /// </summary>
        /// <param name="texture">The texture to bind.</param>
        /// <param name="unit">The texture unit to bind it to.</param>
        public static void BindTexture(TextureGL texture, TextureUnit unit = TextureUnit.Texture0)
        {
            var index = GetTextureUnitId(unit);

            if (last_bound_texture[index] != texture)
            {
                FlushCurrentBatch();

                GL.ActiveTexture(unit);
                GL.BindTexture(TextureTarget.Texture2D, texture?.TextureId ?? 0);
                last_bound_texture[index] = texture;

                FrameStatistics.Increment(StatisticsCounterType.TextureBinds);
            }
        }
예제 #13
0
        private void handleState(object sender, KeyboardKeyEventArgs e)
        {
            var state = e.Keyboard;

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

            lastState = state;

            PendingStates.Enqueue(new InputState {
                Keyboard = new TkKeyboardState(state)
            });
            FrameStatistics.Increment(StatisticsCounterType.KeyEvents);
        }
예제 #14
0
        /// <summary>
        /// Bind an OpenGL buffer object.
        /// </summary>
        /// <param name="target">The buffer type to bind.</param>
        /// <param name="buffer">The buffer ID to bind.</param>
        /// <returns>Whether an actual bind call was necessary. This value is false when repeatedly binding the same buffer.</returns>
        public static bool BindBuffer(BufferTarget target, int buffer)
        {
            int bufferIndex = target - BufferTarget.ArrayBuffer;

            if (last_bound_buffers[bufferIndex] == buffer)
            {
                return(false);
            }

            last_bound_buffers[bufferIndex] = buffer;
            GL.BindBuffer(target, buffer);

            FrameStatistics.Increment(StatisticsCounterType.VBufBinds);

            return(true);
        }
예제 #15
0
        private IEnumerable <Drawable> buildMouseInputQueue(InputState state)
        {
            var positionalInputQueue = new List <Drawable>();

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

            foreach (Drawable d in AliveInternalChildren)
            {
                d.BuildMouseInputQueue(state.Mouse.Position, positionalInputQueue);
            }

            positionalInputQueue.Reverse();
            return(positionalInputQueue);
        }
예제 #16
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>
        public static void BindTexture(int textureId, TextureUnit unit = TextureUnit.Texture0)
        {
            var index = GetTextureUnitId(unit);

            if (last_bound_texture[index] != textureId)
            {
                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);
            }
        }
예제 #17
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);
        }
예제 #18
0
        /// <summary>
        /// Updates this audio component. Always runs on the audio thread.
        /// </summary>
        public virtual void Update()
        {
            ThreadSafety.EnsureNotUpdateThread();
            if (IsDisposed)
            {
                throw new ObjectDisposedException(ToString(), "Can not update disposed audio components.");
            }

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

            Action action;

            while (!IsDisposed && PendingActions.TryDequeue(out action))
            {
                action();
            }
        }
예제 #19
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)
        {
            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);
        }
예제 #20
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)
                {
                    // We multiply the size param by 3 such that the amount of vertices is a multiple of the amount of vertices
                    // per primitive (triangles in this case). Otherwise overflowing the batch will result in wrong
                    // grouping of vertices into primitives.
                    triangleBatch = new LinearBatch <TexturedVertex2D>(512 * 3, 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);
        }
예제 #21
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);
        }
예제 #22
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());
        }
예제 #23
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);
        }
예제 #24
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);
        }
예제 #25
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;
            }
        }
예제 #26
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);
        }
예제 #27
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);
        }
예제 #28
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;
            }
        }
        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);
        }
예제 #30
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);
        }