/// <summary> /// Saves the game's input bindings. /// </summary> protected void SaveInputBindings() { var inputBindingsPath = Path.Combine(GetRoamingApplicationSettingsDirectory(), "InputBindings.xml"); Ultraviolet.GetInput().GetActions().Save(inputBindingsPath); }
/// <summary> /// Creates the effect pass' collection of uniforms. /// </summary> /// <param name="ssmd">The source metadata for this program.</param> /// <returns>The collection of uniforms that was created.</returns> private OpenGLShaderUniformCollection CreateUniformCollection(ShaderSourceMetadata ssmd) { var result = Ultraviolet.QueueWorkItem(state => { var programObject = ((OpenGLShaderProgram)state); var program = programObject.program; var uniforms = new List <OpenGLShaderUniform>(); var samplerCount = 0; var count = gl.GetProgrami(program, gl.GL_ACTIVE_UNIFORMS); gl.ThrowIfError(); for (uint i = 0; i < count; i++) { var type = 0u; var name = gl.GetActiveUniform(program, i, out type); gl.ThrowIfError(); var location = gl.GetUniformLocation(program, name); gl.ThrowIfError(); var isSampler = false; switch (type) { case gl.GL_SAMPLER_1D: case gl.GL_SAMPLER_1D_ARRAY: case gl.GL_SAMPLER_1D_ARRAY_SHADOW: case gl.GL_SAMPLER_1D_SHADOW: case gl.GL_SAMPLER_2D: case gl.GL_SAMPLER_2D_ARRAY: case gl.GL_SAMPLER_2D_ARRAY_SHADOW: case gl.GL_SAMPLER_2D_MULTISAMPLE: case gl.GL_SAMPLER_2D_MULTISAMPLE_ARRAY: case gl.GL_SAMPLER_2D_RECT: case gl.GL_SAMPLER_2D_RECT_SHADOW: case gl.GL_SAMPLER_2D_SHADOW: case gl.GL_SAMPLER_3D: case gl.GL_SAMPLER_CUBE: case gl.GL_SAMPLER_CUBE_MAP_ARRAY: case gl.GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW: case gl.GL_SAMPLER_CUBE_SHADOW: isSampler = true; break; } var sampler = isSampler ? samplerCount++ : -1; if (isSampler && ssmd.PreferredSamplerIndices.ContainsKey(name)) { samplerCount = ssmd.PreferredSamplerIndices[name]; sampler = samplerCount++; } uniforms.Add(new OpenGLShaderUniform(programObject.Ultraviolet, name, type, program, location, sampler)); } return(uniforms); }, this).Result; // Validation: make sure all preferred samplers correspond to an actual uniform var missingUniform = ssmd.PreferredSamplerIndices.Keys.Where(x => !result.Where(y => String.Equals(y.Name, x, StringComparison.Ordinal)).Any()).FirstOrDefault(); if (missingUniform != null) { throw new ArgumentException(OpenGLStrings.SamplerDirectiveInvalidUniform.Format(missingUniform)); } return(new OpenGLShaderUniformCollection(result)); }
private void DrawGamePadState(Int32 playerIndex, Rectangle area) { var input = Ultraviolet.GetInput(); var device = input.GetGamePadForPlayer(playerIndex); var font = content.Load <SpriteFont>(GlobalFontID.SegoeUI); var x = area.X; var y = area.Y; var textArea = RectangleF.Empty; spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, DepthStencilState.Default, RasterizerState.CullCounterClockwise); textFormatter.Reset(); textFormatter.AddArgument(playerIndex + 1); textFormatter.AddArgument(device == null ? "(not connected)" : device.Name); textFormatter.AddArgument((device == null) ? "" : device.GetButtonState(TwistedLogik.Ultraviolet.Input.GamePadButton.A).ToString()); textFormatter.Format("|c:FFFFFF00|Player {0}|c|\n{1}", textBuffer); var headerSettings = new TextLayoutSettings(font, area.Width, area.Height, TextFlags.AlignCenter | TextFlags.AlignTop); textArea = textRenderer.Draw(spriteBatch, textBuffer, new Vector2(x, y), Color.White, headerSettings); y += (Int32)textArea.Height + font.Regular.LineSpacing; if (device != null) { textFormatter.Reset(); textFormatter.AddArgument(device.IsButtonDown(GamePadButton.LeftShoulder) ? "LeftShoulder" : "LeftShoulderDisabled"); textFormatter.AddArgument(device.IsButtonDown(GamePadButton.RightShoulder) ? "RightShoulder" : "RightShoulderDisabled"); textFormatter.AddArgument(device.IsButtonDown(GamePadButton.A) ? "AButton" : "AButtonDisabled"); textFormatter.AddArgument(device.IsButtonDown(GamePadButton.B) ? "BButton" : "BButtonDisabled"); textFormatter.AddArgument(device.IsButtonDown(GamePadButton.X) ? "XButton" : "XButtonDisabled"); textFormatter.AddArgument(device.IsButtonDown(GamePadButton.Y) ? "YButton" : "YButtonDisabled"); textFormatter.AddArgument(device.IsButtonDown(GamePadButton.Back) ? "BackButton" : "BackButtonDisabled"); textFormatter.AddArgument(device.IsButtonDown(GamePadButton.Start) ? "StartButton" : "StartButtonDisabled"); textFormatter.AddArgument(device.IsButtonDown(GamePadButton.DPadUp) ? "DPadUp" : "DPadUpDisabled"); textFormatter.AddArgument(device.IsButtonDown(GamePadButton.DPadDown) ? "DPadDown" : "DPadDownDisabled"); textFormatter.AddArgument(device.IsButtonDown(GamePadButton.DPadLeft) ? "DPadLeft" : "DPadLeftDisabled"); textFormatter.AddArgument(device.IsButtonDown(GamePadButton.DPadRight) ? "DPadRight" : "DPadRightDisabled"); textFormatter.AddArgument(device.IsButtonDown(GamePadButton.LeftStick) ? "LeftJoystick" : "LeftJoystickDisabled"); textFormatter.AddArgument(device.IsButtonDown(GamePadButton.RightStick) ? "RightJoystick" : "RightJoystickDisabled"); textFormatter.Format( "|c:FFFFFF00|Buttons|c|\n\n" + "|icon:{0}| |icon:{1}|\n" + "|icon:{2}| |icon:{3}| |icon:{4}| |icon:{5}|\n" + "|icon:{6}| |icon:{7}|\n" + "|icon:{8}| |icon:{9}| |icon:{10}| |icon:{11}|\n" + "|icon:{12}| |icon:{13}|\n\n" + "|c:FFFFFF00|Axes|c|", textBuffer); var buttonSettings = new TextLayoutSettings(font, area.Width, area.Height, TextFlags.AlignCenter | TextFlags.AlignTop); textArea = textRenderer.Draw(spriteBatch, textBuffer, new Vector2(x, y), Color.White, buttonSettings); y += (Int32)textArea.Height + font.Regular.LineSpacing; var axesLeftSettings = new TextLayoutSettings(font, area.Width, area.Height, TextFlags.AlignLeft | TextFlags.AlignTop); var axesRightSettings = new TextLayoutSettings(font, area.Width, area.Height, TextFlags.AlignRight | TextFlags.AlignTop); textFormatter.Reset(); textFormatter.AddArgument(device.LeftTrigger); textFormatter.Format("|icon:LeftTrigger|{0:decimals:2}", textBuffer); textArea = textRenderer.Draw(spriteBatch, textBuffer, new Vector2(x, y), Color.White, axesLeftSettings); textFormatter.Reset(); textFormatter.AddArgument(device.RightTrigger); textFormatter.Format("{0:decimals:2}|icon:RightTrigger|", textBuffer); textArea = textRenderer.Draw(spriteBatch, textBuffer, new Vector2(x, y), Color.White, axesRightSettings); y += (Int32)textArea.Height; textFormatter.Reset(); textFormatter.AddArgument(device.LeftJoystickX); textFormatter.AddArgument(device.LeftJoystickY); textFormatter.Format("|icon:LeftJoystick|\nX={0:decimals:2}\nY={1:decimals:2}", textBuffer); textArea = textRenderer.Draw(spriteBatch, textBuffer, new Vector2(x, y), Color.White, axesLeftSettings); textFormatter.Reset(); textFormatter.AddArgument(device.RightJoystickX); textFormatter.AddArgument(device.RightJoystickY); textFormatter.Format("|icon:RightJoystick|\nX={0:decimals:2}\nY={1:decimals:2}", textBuffer); textArea = textRenderer.Draw(spriteBatch, textBuffer, new Vector2(x, y), Color.White, axesRightSettings); } spriteBatch.End(); }
private void SaveInputBindings() { Ultraviolet.GetInput().GetActions().Save(GetInputBindingsPath()); }
protected override void LoadContentManifests(ContentManager content) { base.LoadContentManifests(content); Ultraviolet.GetContent().Manifests["Global"]["Fonts"].PopulateAssetLibrary(typeof(GlobalFontID)); }
/// <summary> /// Binds the specified buffer's vertex attributes to the currently cached program using the old API. /// </summary> private unsafe void BindVertexAttributesForBuffer_OldAPI(OpenGLVertexBuffer vbuffer, UInt32 binding, UInt32 frequency, UInt32?program, UInt32?offset) { OpenGLState.BindArrayBuffer(vbuffer.OpenGLName); var position = offset ?? this.offset; var caps = Ultraviolet.GetGraphics().Capabilities; foreach (var element in vbuffer.VertexDeclaration) { var name = GetVertexAttributeNameFromUsage(element.Usage, element.Index); var size = 0; var stride = 0; var normalize = false; var type = GetVertexFormatGL(element.Format, out size, out stride, out normalize); var category = OpenGLAttribCategory.Single; var location = (UInt32)OpenGLState.CurrentProgram.GetAttribLocation(name, out category); if (location >= 0) { if (program.HasValue) { if (gl.IsGLES2) { if (frequency != 0) { throw new NotSupportedException(); } } else { gl.VertexAttribDivisor(location, frequency); gl.ThrowIfError(); } gl.EnableVertexAttribArray(location); gl.ThrowIfError(); } switch (category) { case OpenGLAttribCategory.Single: { gl.VertexAttribPointer(location, size, type, normalize, vbuffer.VertexDeclaration.VertexStride, (void *)(position)); gl.ThrowIfError(); } break; case OpenGLAttribCategory.Double: { if (!caps.SupportsDoublePrecisionVertexAttributes) { throw new NotSupportedException(); } gl.VertexAttribLPointer(location, size, type, vbuffer.VertexDeclaration.VertexStride, (void *)(position)); gl.ThrowIfError(); } break; case OpenGLAttribCategory.Integer: { if (!caps.SupportsIntegerVertexAttributes) { throw new NotSupportedException(); } gl.VertexAttribIPointer(location, size, type, vbuffer.VertexDeclaration.VertexStride, (void *)(position)); gl.ThrowIfError(); } break; } } position += (uint)stride; } }
/// <summary> /// Draws out-of-band elements to their render buffers. /// </summary> /// <param name="time">Time elapsed since the last call to <see cref="UltravioletContext.Draw(UltravioletTime)"/>.</param> public void DrawRenderTargets(UltravioletTime time) { Contract.EnsureNotDisposed(this, Disposed); if (registeredElements.Count == 0) { return; } var graphics = Ultraviolet.GetGraphics(); var upf = Ultraviolet.GetUI().GetPresentationFoundation(); upf.PerformanceStats.BeginDraw(); try { isDrawingRenderTargets = true; foreach (var registeredElement in registeredElements) { var element = (UIElement)registeredElement.Target; if (element != null && element.OutOfBandRenderTarget != null) { element.OutOfBandRenderTarget.Value.IsReady = false; } if (element.View != null && !element.View.LayoutRoot.IsLoaded) { viewsNeedingLoading.Add(element.View); } } foreach (var view in viewsNeedingLoading) { view.EnsureIsLoaded(); } viewsNeedingLoading.Clear(); registeredElements.Sort(uiElementComparer); foreach (var registeredElement in registeredElements) { var element = (UIElement)registeredElement.Target; if (element == null) { deadReferences.Add(registeredElement); continue; } if (element.View == null) { continue; } var bounds = default(RectangleD); var effect = element.Effect; var rtarget = element.OutOfBandRenderTarget.Value; if (rtarget.ResizeForElement(element, out bounds)) { for (var current = rtarget.Next; current != null; current = current.Next) { current.Resize(rtarget.Width, rtarget.Height); } } graphics.SetRenderTarget(rtarget.RenderTarget); graphics.Clear(Color.Transparent); var popup = element as Popup; if (popup != null) { if (!popup.IsOpen) { continue; } element = popup.Root; } if (!element.TransformedVisualBounds.IsEmpty && !IsVisuallyDisconnectedFromRoot(element)) { drawingContext.Reset(element.View.Display); var visualParent = VisualTreeHelper.GetParent(element) as UIElement; var visualTransformOfParent = (visualParent == null) ? popup.PopupTransformToView : visualParent.GetVisualTransformMatrix(); var visualTransformOfElement = element.GetVisualTransformMatrix(ref visualTransformOfParent); rtarget.VisualTransform = visualTransformOfElement; rtarget.VisualBounds = bounds; currentElementDrawingRenderTarget = element; element.DrawToRenderTarget(time, drawingContext, rtarget.RenderTarget, (popup != null) ? popup.PopupTransformToViewInDevicePixels : visualTransformOfParent); if (rtarget.Next != null) { if (effect != null) { effect.DrawRenderTargets(drawingContext, element, rtarget); } } currentElementDrawingRenderTarget = null; rtarget.IsReady = true; } } foreach (var deadReference in deadReferences) { registeredElements.Remove(deadReference); } } finally { isDrawingRenderTargets = false; currentElementDrawingRenderTarget = null; } deadReferences.Clear(); graphics.SetRenderTarget(null); graphics.Clear(Color.Transparent); upf.PerformanceStats.EndDraw(); }
protected override void OnUpdating(UltravioletTime time) { Vector2 scale = animator.Scale; if (Actions.SwitchEntity.IsPressed()) { SwitchEntity(); } if (Actions.NextAnimation.IsPressed()) { animator.Play(animator.GetNextAnimation()); } if (Actions.DecreaseSpeed.IsPressed()) { animator.ChangeAnimationSpeed(-0.2f, 5.0f); } if (Actions.IncreaseSpeed.IsPressed()) { animator.ChangeAnimationSpeed(0.2f, 5.0f); } if (Actions.ReverseAnimation.IsPressed()) { animator.Speed = -animator.Speed; } if (Actions.Transition.IsPressed()) { animator.Transition(animator.GetNextAnimation(), 1000.0f); } if (Actions.PushCharMap.IsPressed()) { animator.PushNextCharacterMap(); } if (Actions.PopCharMap.IsPressed()) { animator.SpriteProvider.PopCharMap(); } if (Actions.ToggleColour.IsPressed()) { animator.Color = animator.Color == Color.White ? Color.Red : Color.White; } if (Actions.MoveUp.IsPressed()) { animator.Position += new Vector2(0, -10); } if (Actions.MoveDown.IsPressed()) { animator.Position += new Vector2(0, 10); } if (Actions.MoveLeft.IsPressed()) { animator.Position += new Vector2(-10, 0); } if (Actions.MoveRight.IsPressed()) { animator.Position += new Vector2(10, 0); } if (Actions.RotateLeft.IsPressed()) { animator.Rotation -= 15 * (float)Math.PI / 180; } if (Actions.RotateRight.IsPressed()) { animator.Rotation += 15 * (float)Math.PI / 180; } if (Actions.ScaleUp.IsPressed()) { animator.Scale += new Vector2(Math.Sign(scale.X) * 0.2f, Math.Sign(scale.Y) * 0.2f); } if (Actions.ScaleDown.IsPressed()) { animator.Scale -= new Vector2(Math.Sign(scale.X) * 0.2f, Math.Sign(scale.Y) * 0.2f); } ; if (Actions.FlipX.IsPressed()) { animator.Scale *= new Vector2(-1, 1); } if (Actions.FlipY.IsPressed()) { animator.Scale *= new Vector2(1, -1); } //if (actions.DrawOutlines.IsPressed()) (currentAnimator as MonoGameDebugAnimator).DrawSpriteOutlines = !(currentAnimator as MonoGameDebugAnimator).DrawSpriteOutlines; if (Actions.ToggleVSync.IsPressed()) { SynchronizeWithVerticalRetrace = !SynchronizeWithVerticalRetrace; } float deltaTime = time.ElapsedTime.Ticks / (float)TimeSpan.TicksPerMillisecond; animator.Update(deltaTime); elapsedTime += deltaTime; if (elapsedTime >= 100) { elapsedTime -= 100; string entity = animator.Entity.Name; status = string.Format("{0} : {1}", entity, animator.Name); metadata = string.Format("Variables:\n{0}\nTags:\n", animator.GetVarValues(), animator.GetTagValues()); textFormatter.Reset(); textFormatter.AddArgument(Ultraviolet.GetGraphics().FrameRate); textFormatter.AddArgument(GC.GetTotalMemory(false) / 1024); textFormatter.AddArgument(Environment.Is64BitProcess ? "64-bit" : "32-bit"); textFormatter.Format("{0:decimals:2} FPS\nAllocated: {1:decimals:2} kb\n{2}", textBuffer); } base.OnUpdating(time); }
/// <inheritdoc/> protected override bool OnValidating(String path, UvssDocument asset) { var upf = Ultraviolet.GetUI().GetPresentationFoundation(); return(upf.TrySetGlobalStyleSheet(this)); }
/// <summary> /// Applies the sampler state to the device. /// </summary> /// <param name="sampler">The sampler index on which to set the state.</param> internal void Apply(Int32 sampler) { Contract.EnsureNotDisposed(this, Disposed); if (Ultraviolet.GetGraphics().Capabilities.SupportsIndependentSamplerState) { throw new InvalidOperationException(UltravioletStrings.GenericError); } OpenGLState.ActiveTexture((uint)(gl.GL_TEXTURE0 + sampler)); gl.TexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, GetTextureAddressModeGL(AddressU)); gl.ThrowIfError(); gl.TexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, GetTextureAddressModeGL(AddressV)); gl.ThrowIfError(); if (MipMapLevelOfDetailBias != 0) { gl.ThrowIfGLES(OpenGLStrings.UnsupportedLODBiasGLES); gl.TexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_LOD_BIAS, MipMapLevelOfDetailBias); gl.ThrowIfError(); } switch (Filter) { case TextureFilter.Point: gl.TexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAX_ANISOTROPY_EXT, 1f); gl.ThrowIfError(); gl.TexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, (int)gl.GL_NEAREST); gl.ThrowIfError(); gl.TexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, (int)gl.GL_NEAREST); gl.ThrowIfError(); break; case TextureFilter.Linear: if (gl.IsAnisotropicFilteringAvailable) { gl.TexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAX_ANISOTROPY_EXT, 1f); gl.ThrowIfError(); } gl.TexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, (int)gl.GL_LINEAR); gl.ThrowIfError(); gl.TexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, (int)gl.GL_LINEAR); gl.ThrowIfError(); break; case TextureFilter.Anisotropic: if (gl.IsAnisotropicFilteringAvailable) { gl.TexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAX_ANISOTROPY_EXT, Math.Min(1f, MaxAnisotropy)); gl.ThrowIfError(); } gl.TexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, (int)gl.GL_LINEAR); gl.ThrowIfError(); gl.TexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, (int)gl.GL_LINEAR); gl.ThrowIfError(); break; default: throw new NotSupportedException(); } }
/// <summary> /// Draws the diagnostics panel to the current window. /// </summary> public void Draw() { LoadContentIfNecessary(); var window = Ultraviolet.GetPlatform().Windows.GetCurrent(); if (window == null) { throw new InvalidOperationException(); } var upf = Ultraviolet.GetUI().GetPresentationFoundation(); var panelWidth = 400; var panelHeight = 16f + (7.5f * font.Regular.LineSpacing); var panelArea = new RectangleF((window.Compositor.Width - panelWidth) / 2, 0, panelWidth, panelHeight); var colorHeader = Color.Yellow; var colorSubheader = new Color(200, 200, 0); var colWidth = (panelWidth - 24) / 3; var xCol1 = panelArea.X + 8f; var xCol2 = xCol1 + colWidth + 8f; var xCol3 = xCol2 + colWidth + 8f; var yLine = 8f; spriteBatch.Begin(); spriteBatch.Draw(blankTexture, panelArea, Color.Black * 0.5f); spriteBatch.DrawString(font, "MEMORY", new Vector2(xCol1, yLine), colorHeader); spriteBatch.DrawString(font, "UPDATE", new Vector2(xCol2, yLine), colorHeader); spriteBatch.DrawString(font, "DRAW", new Vector2(xCol3, yLine), colorHeader); yLine += font.Regular.LineSpacing; formatter.Reset(); formatter.AddArgument(GC.GetTotalMemory(false) / 1024.0); formatter.Format("{0:decimals:2} Kb", buffer); spriteBatch.DrawString(font, buffer, new Vector2(xCol1, yLine), Color.White); formatter.Reset(); formatter.AddArgument(upf.PerformanceStats.TimeInUpdateLastFrame.TotalMilliseconds); formatter.Format("{0:decimals:2} ms", buffer); spriteBatch.DrawString(font, buffer, new Vector2(xCol2, yLine), Color.White); formatter.Reset(); formatter.AddArgument(upf.PerformanceStats.TimeInDrawLastFrame.TotalMilliseconds); formatter.Format("{0:decimals:2} ms", buffer); spriteBatch.DrawString(font, buffer, new Vector2(xCol3, yLine), Color.White); yLine += font.Regular.LineSpacing * 1.5f; spriteBatch.DrawString(font, "POOLS", new Vector2(xCol1, yLine), colorHeader); yLine += font.Regular.LineSpacing; spriteBatch.DrawString(font, "Simple Clock", new Vector2(xCol1, yLine), colorSubheader); spriteBatch.DrawString(font, "Storyboard Instance", new Vector2(xCol2, yLine), colorSubheader); spriteBatch.DrawString(font, "Storyboard Clock", new Vector2(xCol3, yLine), colorSubheader); yLine += font.Regular.LineSpacing; formatter.Reset(); formatter.AddArgument(SimpleClockPool.Instance.Active); formatter.AddArgument(SimpleClockPool.Instance.Available); formatter.AddArgument(SimpleClockPool.Instance.Active + SimpleClockPool.Instance.Available); formatter.Format("{0} / {1} [{2}]", buffer); spriteBatch.DrawString(font, buffer, new Vector2(xCol1, yLine), Color.White); formatter.Reset(); formatter.AddArgument(StoryboardInstancePool.Instance.Active); formatter.AddArgument(StoryboardInstancePool.Instance.Available); formatter.AddArgument(StoryboardInstancePool.Instance.Active + StoryboardInstancePool.Instance.Available); formatter.Format("{0} / {1} [{2}]", buffer); spriteBatch.DrawString(font, buffer, new Vector2(xCol2, yLine), Color.White); formatter.Reset(); formatter.AddArgument(StoryboardClockPool.Instance.Active); formatter.AddArgument(StoryboardClockPool.Instance.Available); formatter.AddArgument(StoryboardClockPool.Instance.Active + StoryboardClockPool.Instance.Available); formatter.Format("{0} / {1} [{2}]", buffer); spriteBatch.DrawString(font, buffer, new Vector2(xCol3, yLine), Color.White); yLine += font.Regular.LineSpacing; spriteBatch.DrawString(font, "OOB Render Target", new Vector2(xCol1, yLine), colorSubheader); spriteBatch.DrawString(font, "Weak Refs", new Vector2(xCol2, yLine), colorSubheader); yLine += font.Regular.LineSpacing; formatter.Reset(); formatter.AddArgument(upf.OutOfBandRenderer.ActiveRenderTargets); formatter.AddArgument(upf.OutOfBandRenderer.AvailableRenderTargets); formatter.AddArgument(upf.OutOfBandRenderer.ActiveRenderTargets + upf.OutOfBandRenderer.AvailableRenderTargets); formatter.Format("{0} / {1} [{2}]", buffer); spriteBatch.DrawString(font, buffer, new Vector2(xCol1, yLine), Color.White); formatter.Reset(); formatter.AddArgument(WeakReferencePool.Instance.Active); formatter.AddArgument(WeakReferencePool.Instance.Available); formatter.AddArgument(WeakReferencePool.Instance.Active + WeakReferencePool.Instance.Available); formatter.Format("{0} / {1} [{2}]", buffer); spriteBatch.DrawString(font, buffer, new Vector2(xCol2, yLine), Color.White); spriteBatch.End(); }
/// <summary> /// Gets the game pad device that corresponds to the specified player index. /// </summary> /// <param name="playerIndex">The index of the player for which to retrieve a game pad device.</param> /// <returns>The game pad device for the specified player, or <see langword="null"/> if no such game pad is connected.</returns> public GamePadDevice GetGamePadForPlayer(Int32 playerIndex) => Ultraviolet.GetInput().GetGamePadForPlayer(playerIndex);
/// <inheritdoc/> public void SetWindowMode(WindowMode mode) { Contract.EnsureNotDisposed(this, Disposed); if (windowMode == mode) { return; } UpdateWindowedPosition(Position); UpdateWindowedClientSize(ClientSize); switch (mode) { case WindowMode.Windowed: { if (SDL_SetWindowFullscreen(ptr, 0) < 0) { throw new SDL2Exception(); } var x = windowedPosition?.X ?? UltravioletConfiguration.DefaultWindowPositionX; var y = windowedPosition?.Y ?? UltravioletConfiguration.DefaultWindowPositionY; var w = windowedClientSize?.Width ?? UltravioletConfiguration.DefaultWindowClientWidth; var h = windowedClientSize?.Height ?? UltravioletConfiguration.DefaultWindowClientHeight; if (!ApplyWin32FullscreenWindowedFix_Windowed()) { SDL_SetWindowBordered(ptr, true); } SDL_SetWindowSize(ptr, w, h); SDL_SetWindowPosition(ptr, x, y); if (Ultraviolet.Platform == UltravioletPlatform.Windows) { win32CachedStyle = IntPtr.Zero; } } break; case WindowMode.Fullscreen: { if (displayMode != null) { if (displayMode.DisplayIndex.HasValue) { var display = Ultraviolet.GetPlatform().Displays[displayMode.DisplayIndex.Value]; ChangeDisplay(display); } } else { SetDesktopDisplayMode(); } if (SDL_SetWindowFullscreen(ptr, (uint)SDL_WINDOW_FULLSCREEN) < 0) { throw new SDL2Exception(); } if (Ultraviolet.Platform == UltravioletPlatform.Windows) { win32CachedStyle = IntPtr.Zero; } } break; case WindowMode.FullscreenWindowed: { if (SDL_SetWindowFullscreen(ptr, 0) < 0) { throw new SDL2Exception(); } var displayBounds = Display.Bounds; if (!ApplyWin32FullscreenWindowedFix_FullscreenWindowed()) { SDL_SetWindowBordered(ptr, false); } SDL_SetWindowSize(ptr, displayBounds.Width, displayBounds.Height); SDL_SetWindowPosition(ptr, displayBounds.X, displayBounds.Y); } break; default: throw new NotSupportedException(nameof(mode)); } windowMode = mode; UpdateMouseGrab(); }
/// <inheritdoc/> public override Int32 GetAlignmentUnit() { return(Math.Max(1, ((OpenGLGraphicsCapabilities)Ultraviolet.GetGraphics().Capabilities).MinMapBufferAlignment)); }
/// <summary> /// Initializes a new instance of the OpenGLShaderProgram class. /// </summary> /// <param name="uv">The Ultraviolet context.</param> /// <param name="vertexShader">The program's vertex shader.</param> /// <param name="fragmentShader">The program's fragment shader.</param> /// <param name="programOwnsShaders">A value indicating whether the program owns the shader objects.</param> public OpenGLShaderProgram(UltravioletContext uv, OpenGLVertexShader vertexShader, OpenGLFragmentShader fragmentShader, Boolean programOwnsShaders) : base(uv) { Contract.Require(vertexShader, nameof(vertexShader)); Contract.Require(fragmentShader, nameof(fragmentShader)); Ultraviolet.ValidateResource(vertexShader); Ultraviolet.ValidateResource(fragmentShader); this.vertexShader = vertexShader; this.fragmentShader = fragmentShader; this.programOwnsShaders = programOwnsShaders; var program = 0u; uv.QueueWorkItemAndWait(() => { program = gl.CreateProgram(); gl.ThrowIfError(); gl.AttachShader(program, vertexShader.OpenGLName); gl.ThrowIfError(); gl.AttachShader(program, fragmentShader.OpenGLName); gl.ThrowIfError(); gl.LinkProgram(program); gl.ThrowIfError(); var log = gl.GetProgramInfoLog(program); gl.ThrowIfError(); var status = gl.GetProgrami(program, gl.GL_LINK_STATUS); gl.ThrowIfError(); var attributeCount = gl.GetProgrami(program, gl.GL_ACTIVE_ATTRIBUTES); gl.ThrowIfError(); unsafe { var namebuf = Marshal.AllocHGlobal(256); try { for (int i = 0; i < attributeCount; i++) { var attrNameLen = 0; var attrName = default(String); var attrSize = 0; var attrType = 0u; gl.GetActiveAttrib(program, (uint)i, 256, &attrNameLen, &attrSize, &attrType, (sbyte *)namebuf); gl.ThrowIfError(); attrName = Marshal.PtrToStringAnsi(namebuf); var location = gl.GetAttribLocation(program, attrName); gl.ThrowIfError(); attributeLocations[attrName] = location; attributeTypes[attrName] = attrType; } } finally { Marshal.FreeHGlobal(namebuf); } } if (status == 0) { throw new InvalidOperationException(log); } }); this.program = program; this.uniforms = CreateUniformCollection(); }
/// <inheritdoc/> public override void SetDataAligned <T>(T[] data, Int32 dataOffset, Int32 dataCount, Int32 bufferOffset, out Int32 bufferSize, SetDataOptions options) { Contract.Require(data, nameof(data)); Contract.EnsureRange(dataCount > 0, nameof(dataCount)); Contract.EnsureRange(dataOffset >= 0 && dataOffset + dataCount <= data.Length, nameof(dataOffset)); Contract.EnsureRange(bufferOffset >= 0, nameof(bufferOffset)); var inputElemSize = Marshal.SizeOf(typeof(T)); var inputSizeInBytes = inputElemSize * dataCount; if (inputSizeInBytes > size.ToInt32()) { throw new InvalidOperationException(OpenGLStrings.DataTooLargeForBuffer); } bufferSize = inputSizeInBytes; var handle = GCHandle.Alloc(data, GCHandleType.Pinned); try { var caps = (OpenGLGraphicsCapabilities)Ultraviolet.GetGraphics().Capabilities; if (caps.MinMapBufferAlignment > 0) { bufferSize = Math.Min(Math.Max(caps.MinMapBufferAlignment, MathUtil.FindNextPowerOfTwo(bufferSize)), SizeInBytes - bufferOffset); } using (OpenGLState.ScopedBindArrayBuffer(buffer)) { var isPartialUpdate = (bufferOffset > 0 || bufferSize < SizeInBytes); var isDiscarding = (options == SetDataOptions.Discard); if (isDiscarding || !isPartialUpdate) { gl.NamedBufferData(buffer, gl.GL_ARRAY_BUFFER, this.size, isPartialUpdate ? null : handle.AddrOfPinnedObject().ToPointer(), usage); gl.ThrowIfError(); /* FIX: * I have no idea why the following code is necessary, but * it seems to fix flickering sprites on Intel HD 4000 devices. */ if (gl.IsVertexArrayObjectAvailable) { var vao = (uint)OpenGLState.GL_VERTEX_ARRAY_BINDING; gl.BindVertexArray(vao); gl.ThrowIfError(); } } if (isPartialUpdate) { if (caps.MinMapBufferAlignment >= 0) { var bufferRangeAccess = gl.GL_MAP_WRITE_BIT | (options == SetDataOptions.NoOverwrite ? gl.GL_MAP_UNSYNCHRONIZED_BIT : 0); var bufferRangePtr = (Byte *)gl.MapNamedBufferRange(buffer, gl.GL_ARRAY_BUFFER, (IntPtr)bufferOffset, (IntPtr)bufferSize, bufferRangeAccess); gl.ThrowIfError(); var sourceRangePtr = (Byte *)handle.AddrOfPinnedObject() + (dataOffset * inputElemSize); var sourceSizeInBytes = dataCount * inputElemSize; for (int i = 0; i < sourceSizeInBytes; i++) { *bufferRangePtr++ = *sourceRangePtr++; } gl.UnmapNamedBuffer(buffer, gl.GL_ARRAY_BUFFER); gl.ThrowIfError(); } else { gl.NamedBufferSubData(buffer, gl.GL_ARRAY_BUFFER, (IntPtr)bufferOffset, (IntPtr)bufferSize, (Byte *)handle.AddrOfPinnedObject().ToPointer() + (dataOffset * inputElemSize)); gl.ThrowIfError(); } } } } finally { handle.Free(); } }
/// <summary> /// Creates a new keyboard binding. /// </summary> /// <param name="key">The binding's primary key.</param> /// <param name="control">A value indicating whether the binding requires the Control modifier.</param> /// <param name="alt">A value indicating whether the binding requires the Alt modifier.</param> /// <param name="shift">A value indicating whether the binding requires the Shift modifier.</param> /// <returns>The binding that was created.</returns> protected InputBinding CreateKeyboardBinding(Key key, Boolean control = false, Boolean alt = false, Boolean shift = false) { return(Ultraviolet.GetInput().IsKeyboardSupported() ? new KeyboardInputBinding(Ultraviolet, key, control, alt, shift) : null); }
/// <summary> /// Loads the game's cursors. /// </summary> protected void LoadCursors() { this.cursors = this.content.Load <CursorCollection>("Cursors/Cursors"); Ultraviolet.GetPlatform().Cursor = this.cursors["Normal"]; }
/// <summary> /// Creates a new mouse binding. /// </summary> /// <param name="button">The binding's primary button.</param> /// <param name="control">A value indicating whether the binding requires the Control modifier.</param> /// <param name="alt">A value indicating whether the binding requires the Alt modifier.</param> /// <param name="shift">A value indicating whether the binding requires the Shift modifier.</param> /// <returns>The binding that was created.</returns> protected InputBinding CreateMouseBinding(MouseButton button, Boolean control = false, Boolean alt = false, Boolean shift = false) { return(Ultraviolet.GetInput().IsMouseSupported() ? new MouseInputBinding(Ultraviolet, button, control, alt, shift) : null); }
protected override void OnUpdating(UltravioletTime time) { var window = Ultraviolet.GetPlatform().Windows.GetPrimary(); if (window != null) { this.textBlock.ChangeSize( window.DrawableSize.Width / 2, window.DrawableSize.Height / 2); this.textBlock.Update(time); } if (Ultraviolet.GetInput().GetActions().ResetScrollingText.IsPressed() || (Ultraviolet.GetInput().GetPrimaryTouchDevice()?.WasTapped() ?? false)) { textBlock.Reset(); } if (Ultraviolet.GetInput().GetActions().ExitApplication.IsPressed()) { Exit(); } base.OnUpdating(time); }
/// <summary> /// Creates a new game pad binding. /// </summary> /// <param name="playerIndex">The index of the player for which to create the binding.</param> /// <param name="button">The binding's primary button.</param> /// <returns>The binding that was created.</returns> protected InputBinding CreateGamePadBinding(Int32 playerIndex, GamePadButton button) { return(Ultraviolet.GetInput().IsGamePadSupported() ? new GamePadInputBinding(Ultraviolet, playerIndex, button) : null); }
/// <summary> /// Binds the specified buffer's vertex attributes to the currently cached program using the new API. /// </summary> private unsafe void BindVertexAttributesForBuffer_NewAPI(OpenGLVertexBuffer vbuffer, UInt32 binding, UInt32 frequency, UInt32?program, UInt32?offset) { var caps = Ultraviolet.GetGraphics().Capabilities; using (OpenGLState.ScopedBindVertexArrayObject(vao, glElementArrayBufferBinding ?? 0)) { if (program.HasValue || offset.HasValue) { gl.VertexArrayVertexBuffer(vao, binding, vbuffer.OpenGLName, (IntPtr)(offset ?? 0), vbuffer.VertexDeclaration.VertexStride); gl.ThrowIfError(); } if (program.HasValue) { gl.VertexArrayBindingDivisor(vao, binding, frequency); gl.ThrowIfError(); var position = 0u; foreach (var element in vbuffer.VertexDeclaration) { var name = GetVertexAttributeNameFromUsage(element.Usage, element.Index); var size = 0; var stride = 0; var normalize = false; var type = GetVertexFormatGL(element.Format, out size, out stride, out normalize); var category = OpenGLAttribCategory.Single; var location = (UInt32)OpenGLState.CurrentProgram.GetAttribLocation(name, out category); if (location >= 0) { gl.VertexArrayAttribBinding(vao, location, binding); gl.ThrowIfError(); gl.EnableVertexArrayAttrib(vao, location); gl.ThrowIfError(); unsafe { switch (category) { case OpenGLAttribCategory.Single: { gl.VertexArrayAttribFormat(vao, location, size, type, normalize, position); gl.ThrowIfError(); } break; case OpenGLAttribCategory.Double: { if (!caps.SupportsDoublePrecisionVertexAttributes) { throw new NotSupportedException(); } gl.VertexArrayAttribLFormat(vao, location, size, type, position); gl.ThrowIfError(); } break; case OpenGLAttribCategory.Integer: { if (!caps.SupportsIntegerVertexAttributes) { throw new NotSupportedException(); } gl.VertexArrayAttribIFormat(vao, location, size, type, position); gl.ThrowIfError(); } break; } } } position += (uint)stride; } } } }
/// <inheritdoc/> public override Int32 GetAlignmentUnit() { Contract.EnsureNotDisposed(this, Disposed); return(Math.Max(1, ((OpenGLGraphicsCapabilities)Ultraviolet.GetGraphics().Capabilities).MinMapBufferAlignment)); }
private void LoadInputBindings() { Ultraviolet.GetInput().GetActions().Load(GetInputBindingsPath(), throwIfNotFound: false); }
/// <inheritdoc/> public override void SetDataAligned <T>(T[] data, Int32 dataOffset, Int32 dataCount, Int32 bufferOffset, out Int32 bufferSize, SetDataOptions options) { Contract.Require(data, nameof(data)); Contract.EnsureRange(dataCount > 0, nameof(dataCount)); Contract.EnsureRange(dataOffset >= 0 && dataOffset + dataCount <= data.Length, nameof(dataOffset)); Contract.EnsureRange(bufferOffset >= 0, nameof(bufferOffset)); Contract.Ensure(dataCount <= IndexCount, OpenGLStrings.DataTooLargeForBuffer); var indexStride = GetElementSize(); bufferSize = indexStride * dataCount; var handle = GCHandle.Alloc(data, GCHandleType.Pinned); try { var caps = (OpenGLGraphicsCapabilities)Ultraviolet.GetGraphics().Capabilities; if (caps.SupportsMapBufferRange && caps.MinMapBufferAlignment > 0) { bufferSize = Math.Min(Math.Max(caps.MinMapBufferAlignment, MathUtil.FindNextPowerOfTwo(bufferSize)), SizeInBytes - bufferOffset); } using (OpenGLState.ScopedBindElementArrayBuffer(buffer)) { var isPartialUpdate = (bufferOffset > 0 || bufferSize < SizeInBytes); var isDiscarding = (options == SetDataOptions.Discard); if (isDiscarding || !isPartialUpdate) { gl.NamedBufferData(buffer, gl.GL_ELEMENT_ARRAY_BUFFER, this.size, isPartialUpdate ? null : handle.AddrOfPinnedObject().ToPointer(), usage); gl.ThrowIfError(); } if (isPartialUpdate) { if (caps.SupportsMapBufferRange) { var bufferRangeAccess = gl.GL_MAP_WRITE_BIT | (options == SetDataOptions.NoOverwrite ? gl.GL_MAP_UNSYNCHRONIZED_BIT : 0); var bufferRangePtr = (Byte *)gl.MapNamedBufferRange(buffer, gl.GL_ELEMENT_ARRAY_BUFFER, (IntPtr)bufferOffset, (IntPtr)bufferSize, bufferRangeAccess); gl.ThrowIfError(); var sourceRangePtr = (Byte *)handle.AddrOfPinnedObject() + (dataOffset * indexStride); var sourceSizeInBytes = dataCount * indexStride; for (int i = 0; i < sourceSizeInBytes; i++) { *bufferRangePtr++ = *sourceRangePtr++; } gl.UnmapNamedBuffer(buffer, gl.GL_ELEMENT_ARRAY_BUFFER); gl.ThrowIfError(); } else { gl.NamedBufferSubData(buffer, gl.GL_ELEMENT_ARRAY_BUFFER, (IntPtr)bufferOffset, (IntPtr)bufferSize, (Byte *)handle.AddrOfPinnedObject().ToPointer() + (dataOffset * indexStride)); gl.ThrowIfError(); } } } } finally { handle.Free(); } }
/// <summary> /// Loads the game's input bindings. /// </summary> protected void LoadInputBindings() { var inputBindingsPath = Path.Combine(GetRoamingApplicationSettingsDirectory(), "InputBindings.xml"); Ultraviolet.GetInput().GetActions().Load(inputBindingsPath, throwIfNotFound: false); }
/// <inheritdoc/> public void SetTexture(Int32 sampler, Texture texture) { Contract.EnsureRange(sampler >= 0 && sampler < maxTextureStages, nameof(sampler)); Contract.EnsureNotDisposed(this, Disposed); Ultraviolet.ValidateResource(texture); if (texture != null && texture.BoundForWriting) { throw new InvalidOperationException(OpenGLStrings.RenderBufferCannotBeUsedAsTexture); } if (texture != null && texture.WillNotBeSampled) { throw new InvalidOperationException(OpenGLStrings.RenderBufferWillNotBeSampled); } if (this.textures[sampler] != texture) { var textureName = (texture == null) ? 0 : ((IOpenGLResource)texture).OpenGLName; OpenGLState.ActiveTexture((uint)(gl.GL_TEXTURE0 + sampler)); if (texture is Texture3D) { OpenGLState.BindTexture3D(textureName); } else { OpenGLState.BindTexture2D(textureName); } if (this.textures[sampler] != null) { ((IBindableResource)this.textures[sampler]).UnbindRead(); } this.textures[sampler] = texture; if (this.textures[sampler] != null) { ((IBindableResource)this.textures[sampler]).BindRead(); if (texture is IOpenGLDynamicTexture textdyn) { textdyn.Flush(); } } if (!Capabilities.SupportsIndependentSamplerState) { var samplerState = (OpenGLSamplerState)(GetSamplerState(sampler) ?? SamplerState.LinearClamp); for (int i = 0; i < samplerStates.Length; i++) { if (this.textures[i] == texture) { var target = (texture is Texture3D) ? gl.GL_TEXTURE_3D : gl.GL_TEXTURE_2D; samplerState.Apply(sampler, target); } } } } }
/// <inheritdoc/> public override IntPtr CreateOpenGLContext() { var masterWindowPtr = ((SDL2UltravioletWindowInfo)Ultraviolet.GetPlatform().Windows).GetMasterPointer(); return(SDL_GL_CreateContext(masterWindowPtr)); }
/// <summary> /// Sets the window's fullscreen display mode. /// </summary> /// <param name="displayMode">The fullscreen display mode to set, or null to use the desktop display mode.</param> private void SetFullscreenDisplayModeInternal(DisplayMode displayMode) { if (displayMode == null) { SetDesktopDisplayMode(); } else { SDL_DisplayMode sdlMode; sdlMode.w = displayMode.Width; sdlMode.h = displayMode.Height; sdlMode.refresh_rate = displayMode.RefreshRate; switch (displayMode.BitsPerPixel) { case 15: sdlMode.format = SDL_PixelFormatEnum.RGB555; break; case 16: sdlMode.format = SDL_PixelFormatEnum.RGB565; break; default: sdlMode.format = SDL_PixelFormatEnum.RGB888; break; } var wasFullscreen = windowMode == WindowMode.Fullscreen; if (wasFullscreen) { SetWindowMode(WindowMode.Windowed); } if (SDL.SetWindowDisplayMode(ptr, &sdlMode) < 0) { throw new SDL2Exception(); } if (wasFullscreen) { if (displayMode.DisplayIndex.HasValue) { ChangeDisplay(displayMode.DisplayIndex.Value); } SetWindowMode(WindowMode.Fullscreen); } if (SDL.GetWindowDisplayMode(ptr, &sdlMode) < 0) { throw new SDL2Exception(); } int bpp; uint Rmask, Gmask, Bmask, Amask; SDL.PixelFormatEnumToMasks((uint)sdlMode.format, &bpp, &Rmask, &Gmask, &Bmask, &Amask); var displayIndex = displayMode.DisplayIndex; if (displayIndex.HasValue) { if (displayIndex < 0 || displayIndex >= Ultraviolet.GetPlatform().Displays.Count) { displayIndex = null; } } displayMode = new DisplayMode(sdlMode.w, sdlMode.h, bpp, sdlMode.refresh_rate, displayIndex); } this.displayMode = displayMode; }