示例#1
0
        /// <summary>
        /// Saves the game's input bindings.
        /// </summary>
        protected void SaveInputBindings()
        {
            var inputBindingsPath = Path.Combine(GetRoamingApplicationSettingsDirectory(), "InputBindings.xml");

            Ultraviolet.GetInput().GetActions().Save(inputBindingsPath);
        }
示例#2
0
        /// <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));
        }
示例#3
0
        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();
        }
示例#4
0
 private void SaveInputBindings()
 {
     Ultraviolet.GetInput().GetActions().Save(GetInputBindingsPath());
 }
示例#5
0
        protected override void LoadContentManifests(ContentManager content)
        {
            base.LoadContentManifests(content);

            Ultraviolet.GetContent().Manifests["Global"]["Fonts"].PopulateAssetLibrary(typeof(GlobalFontID));
        }
示例#6
0
        /// <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();
        }
示例#8
0
        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);
        }
示例#9
0
        /// <inheritdoc/>
        protected override bool OnValidating(String path, UvssDocument asset)
        {
            var upf = Ultraviolet.GetUI().GetPresentationFoundation();

            return(upf.TrySetGlobalStyleSheet(this));
        }
示例#10
0
        /// <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();
            }
        }
示例#11
0
            /// <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);
示例#13
0
        /// <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);
 }
示例#18
0
 /// <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);
 }
示例#20
0
        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);
 }
示例#22
0
        /// <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;
                    }
                }
            }
        }
示例#23
0
        /// <inheritdoc/>
        public override Int32 GetAlignmentUnit()
        {
            Contract.EnsureNotDisposed(this, Disposed);

            return(Math.Max(1, ((OpenGLGraphicsCapabilities)Ultraviolet.GetGraphics().Capabilities).MinMapBufferAlignment));
        }
示例#24
0
 private void LoadInputBindings()
 {
     Ultraviolet.GetInput().GetActions().Load(GetInputBindingsPath(), throwIfNotFound: false);
 }
示例#25
0
        /// <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();
            }
        }
示例#26
0
        /// <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;
        }