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); }
protected override void UpdateState() { FrameStatistics.Increment(StatisticsCounterType.Tracks); if (Looping && HasReachedEnd) { Restart(); } base.UpdateState(); }
/// <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); }
public override void Update() { FrameStatistics.Increment(StatisticsCounterType.Tracks); base.Update(); if (Looping && !IsRunning && Length == CurrentTime) { Reset(); Start(); } }
protected void Validate() { if (IsValid) { return; } IsValid = true; Parent?.ValidateSuperTree(Invalidation); FrameStatistics.Increment(StatisticsCounterType.Refreshes); }
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); }
public override void Update() { FrameStatistics.Increment(StatisticsCounterType.Tracks); if (Looping && HasCompleted) { Reset(); Start(); } base.Update(); }
/// <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); } }
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); }
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); }
/// <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); }
/// <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); } }
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); }
/// <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); }
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); }
/// <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); } }
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); }
/// <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(); } }
/// <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); }
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); }
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); }
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()); }
/// <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); }
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); }
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; } }
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); }
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); }
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); }
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); }