예제 #1
0
        internal static void BloomEnd()
        {
            if (!(ConfigManager.sBloomSoftening || ExtraPass))
            {
                return;
            }
            renderTarget.Unbind();

#if !DEBUG
            try
            {
#endif
            // If we rendered everything to a frame buffer object, then we first need to blit it to the backbuffer.
            if (OsuGlControl.CanUseFBO)
            {
                OsuGlControl.SetBlend(BlendingFactorSrc.One, BlendingFactorDest.Zero);
                renderTarget.Texture.Draw(Vector2.Zero, Vector2.Zero, Color.White, new Vector2(1, -1), 0, null);
            }

            OsuGlControl.SetBlend(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);

            bloomShader.Begin();
            if (ConfigManager.sBloomSoftening)
            {
                bloomShader.Properties[@"mag"]     = 0.004f;
                bloomShader.Properties[@"alpha"]   = 0.15f;
                bloomShader.Properties[@"hirange"] = false;
                bloomShader.Properties[@"redtint"] = 0f;
                renderTarget.Texture.Draw(Vector2.Zero, Vector2.Zero, Color.White, new Vector2(1, -1), 0, null);
            }

            if (ExtraPass)
            {
                bloomShader.Properties[@"mag"]     = Magnitude;
                bloomShader.Properties[@"alpha"]   = Alpha;
                bloomShader.Properties[@"hirange"] = HiRange;
                bloomShader.Properties[@"redtint"] = RedTint;

                if (Additive)
                {
                    OsuGlControl.SetBlend(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.One);
                }

                renderTarget.Texture.Draw(Vector2.Zero, Vector2.Zero, Color.White, new Vector2(1, -1), 0, null);

                if (Additive)
                {
                    OsuGlControl.SetBlend(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
                }
            }
            bloomShader.End();
#if !DEBUG
        }

        catch
        {
            //Todo:
        }
#endif
        }
예제 #2
0
        public QuadVertexBuffer(int amountQuads, BufferUsageHint usage)
            : base(amountQuads * 4, usage)
        {
            int amountIndices = amountQuads * 6;

            if (amountIndices > QuadIndexData.MaxAmountIndices)
            {
                ushort[] indices = new ushort[amountIndices];

                for (ushort i = 0, j = 0; j < amountIndices; i += 4, j += 6)
                {
                    indices[j]     = i;
                    indices[j + 1] = (ushort)(i + 1);
                    indices[j + 2] = (ushort)(i + 3);
                    indices[j + 3] = (ushort)(i + 2);
                    indices[j + 4] = (ushort)(i + 3);
                    indices[j + 5] = (ushort)(i + 1);
                }

                OsuGlControl.BindBuffer(BufferTarget.ElementArrayBuffer, QuadIndexData.EboId);
                GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(amountIndices * sizeof(ushort)), indices, BufferUsageHint.StaticDraw);

                QuadIndexData.MaxAmountIndices = amountIndices;
            }
        }
예제 #3
0
        private void startBatch(bool allowRecycle = false)
        {
            if (hasBegun && !allowRecycle)
            {
                return;
            }

            endBatch();

            int amountQuads = OsuMathHelper.Clamp(SpriteList.Count, 1, 100);

            if (SpriteBatch == null || SpriteBatch.Size < amountQuads)
            {
                for (int i = 0; i < SpriteBatches.Length; i++)
                {
                    SpriteBatches[i] = new QuadBatch <TexturedVertex2d>(amountQuads * 2, 500);
                }
            }

            if (currentBlend == SpriteBlendMode.Additive)
            {
                OsuGlControl.SetBlend(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.One);
            }
            else
            {
                OsuGlControl.SetBlend(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
            }

            hasBegun = true;
            Current  = this;
            NativeText.ScaleModifier = Scale;
        }
예제 #4
0
        public override void Bind(bool forRendering)
        {
            base.Bind(forRendering);

            if (forRendering)
            {
                OsuGlControl.BindBuffer(BufferTarget.ElementArrayBuffer, LinearIndexData.EboId);
            }
        }
예제 #5
0
        public virtual void Bind(bool forRendering)
        {
            Debug.Assert(!isDisposed);

            if (OsuGlControl.BindBuffer(BufferTarget.ArrayBuffer, vboId))
            {
                bindAttributes();
            }
        }
예제 #6
0
        public override bool Draw()
        {
            if (!base.Draw())
            {
                return(false);
            }

            Progress = (float)Math.Min(1.0, Progress);

            float scaledOuterRingRadius = Radius * Scale * GameBase.WindowManager.RatioInverse;
            float scaledGlowWidth       = GlowWidth * Scale * GameBase.WindowManager.RatioInverse;
            float scaledInnerRingRadius = (float)Math.Min(scaledOuterRingRadius, Math.Max(0.0, (Radius - LineWidth) * Scale * GameBase.WindowManager.RatioInverse));

            Vector2 scaledPosition = Position * GameBase.WindowManager.Ratio;

            vertexBuffer.Vertices[0].Position = scaledPosition + new Vector2(-scaledOuterRingRadius - scaledGlowWidth, -scaledOuterRingRadius - scaledGlowWidth);
            vertexBuffer.Vertices[1].Position = scaledPosition + new Vector2(-scaledOuterRingRadius - scaledGlowWidth, scaledOuterRingRadius + scaledGlowWidth);
            vertexBuffer.Vertices[2].Position = scaledPosition + new Vector2(scaledOuterRingRadius + scaledGlowWidth, scaledOuterRingRadius + scaledGlowWidth);
            vertexBuffer.Vertices[3].Position = scaledPosition + new Vector2(scaledOuterRingRadius + scaledGlowWidth, -scaledOuterRingRadius - scaledGlowWidth);

            vertexBuffer.Update();

            circularProgressBarShader.Properties[@"m_CenterPos"]       = new OpenTK.Vector2(scaledPosition.X, scaledPosition.Y);
            circularProgressBarShader.Properties[@"m_OuterRadius"]     = scaledOuterRingRadius;
            circularProgressBarShader.Properties[@"m_InnerRadius"]     = scaledInnerRingRadius;
            circularProgressBarShader.Properties[@"m_OuterGlowRadius"] = scaledOuterRingRadius + scaledGlowWidth;
            circularProgressBarShader.Properties[@"m_InnerGlowRadius"] = scaledInnerRingRadius - scaledGlowWidth;

            circularProgressBarShader.Properties[@"m_Alpha"] = Alpha;

            circularProgressBarShader.Properties[@"m_GlowColour"]           = _glowColour;
            circularProgressBarShader.Properties[@"m_RingBackgroundColour"] = _ringBackgroundColour;
            circularProgressBarShader.Properties[@"m_RingForegroundColour"] = _ringForegroundColour;

            circularProgressBarShader.Properties[@"m_Progress"] = Progress;

            OsuGlControl.SetBlend(BlendingFactorSrc.One, BlendingFactorDest.One);

            circularProgressBarShader.Begin();
            vertexBuffer.Draw();
            circularProgressBarShader.End();

            return(true);
        }
예제 #7
0
        public LinearVertexBuffer(int amountVertices, BeginMode type, BufferUsageHint usage)
            : base(amountVertices, usage)
        {
            this.type = type;

            if (amountVertices > LinearIndexData.MaxAmountIndices)
            {
                ushort[] indices = new ushort[amountVertices];

                for (ushort i = 0; i < amountVertices; i++)
                {
                    indices[i] = i;
                }

                OsuGlControl.BindBuffer(BufferTarget.ElementArrayBuffer, LinearIndexData.EboId);
                GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(amountVertices * sizeof(ushort)), indices, BufferUsageHint.StaticDraw);

                LinearIndexData.MaxAmountIndices = amountVertices;
            }
        }
예제 #8
0
        public void Draw()
        {
            if (ConfigManager.dDisableSpriteDraw)
            {
                return;
            }

            pTexture trail = SkinManager.t_cursortrail;

            if (amountVisibleRanges == 0 || trail == null || trail.IsDisposed)
            {
                return;
            }

            if (trail.TextureGl.Bind())
            {
                cursorTrailShader.Properties[@"g_FadeClock"] = fadeClock;
                cursorTrailShader.Begin();

                OsuGlControl.SetBlend(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.One);

                for (int i = 0; i < amountNewRanges; i += 2)
                {
                    for (int j = newIndexRanges[i]; j < newIndexRanges[i + 1]; ++j)
                    {
                        needsUpload[j] = false;
                    }

                    vertexBuffer.UpdateRange(newIndexRanges[i] * 4, newIndexRanges[i + 1] * 4);
                }

                for (int i = 0; i < amountVisibleRanges; i += 2)
                {
                    vertexBuffer.DrawRange(visibleIndexRanges[i] * 4, visibleIndexRanges[i + 1] * 4);
                }

                cursorTrailShader.End();
            }
        }
예제 #9
0
        public void Resize(int amountVertices)
        {
            Debug.Assert(!isDisposed);

            T[] oldVertices = Vertices;
            Vertices = new T[amountVertices];

            if (oldVertices != null)
            {
                for (int i = 0; i < oldVertices.Length && i < Vertices.Length; ++i)
                {
                    Vertices[i] = oldVertices[i];
                }
            }

            if (OsuGlControl.BindBuffer(BufferTarget.ArrayBuffer, vboId))
            {
                bindAttributes();
            }

            GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(Vertices.Length * stride), IntPtr.Zero, usage);
        }
        /// <summary>
        /// Core drawing method in OpenGL
        /// </summary>
        /// <param name="lineList">List of lines to use</param>
        /// <param name="globalRadius">Width of the slider</param>
        /// <param name="texture">Texture used for the track</param>
        /// <param name="prev">The last line which was rendered in the previous iteration, or null if this is the first iteration.</param>
        private void DrawOGL(List <Line> lineList, float globalRadius, TextureGl texture, Line prev, int lineCount)
        {
            GL.Disable(EnableCap.CullFace);
            GL.Disable(EnableCap.Blend);
            GL.Enable(EnableCap.DepthTest);
            GL.DepthMask(true);
            GL.DepthFunc(DepthFunction.Lequal);

            GL.Clear(ClearBufferMask.DepthBufferBit);

            OsuGlControl.TextureShader3D.Begin();

            OsuGlControl.BindTexture(texture.TextureId);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)All.Linear);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)All.Linear);

            if (lineCount == -1)
            {
                lineCount = lineList.Count;
            }

            for (int x = 1; x < lineCount; x++)
            {
                DrawLineOGL(prev, lineList[x - 1], lineList[x], globalRadius);
                prev = lineList[x - 1];
            }

            DrawLineOGL(prev, lineList[lineCount - 1], null, globalRadius);

            quadBatch.Draw();
            halfCircleBatch.Draw();

            OsuGlControl.TextureShader3D.End();

            GL.Disable(EnableCap.DepthTest);
            GL.DepthMask(false);
            GL.Enable(EnableCap.Blend);
        }
예제 #11
0
        /// <summary>
        ///   Draws this instance.
        /// </summary>
        internal bool Draw()
        {
            lock (SpriteLock)
            {
                if (FirstDraw)
                {
                    HandleFirstDraw();
                }

                int spriteListCount = SpriteList.Count;
                PixelsDrawn = 0;

                //Setup view rectangle
                if (viewRectangleCustom)
                {
                    ViewRectangleScaled =
                        new RectangleF(
                            (float)Math.Floor((WidescreenAutoOffset ? GameBase.WindowManager.NonWidescreenOffsetX : 0) + ViewRectangle.X * GameBase.WindowManager.Ratio),
                            (float)Math.Floor(ViewRectangle.Y * GameBase.WindowManager.Ratio),
                            (float)Math.Ceiling(ViewRectangle.Width * GameBase.WindowManager.Ratio),
                            (float)Math.Ceiling(ViewRectangle.Height * GameBase.WindowManager.Ratio));
                }
                else if (WidescreenAutoOffset)
                {
                    ViewRectangleScaled = new RectangleF(
                        GameBase.WindowManager.NonWidescreenOffsetX + ViewRectangle43.X * GameBase.WindowManager.Ratio,
                        ViewRectangle43.Y * GameBase.WindowManager.Ratio,
                        ViewRectangle43.Width * GameBase.WindowManager.Ratio, ViewRectangle43.Height * GameBase.WindowManager.Ratio);
                }
                else
                {
                    ViewRectangleScaled = new RectangleF(ViewRectangleCurrent.X * GameBase.WindowManager.Ratio,
                                                         ViewRectangleCurrent.Y * GameBase.WindowManager.Ratio,
                                                         ViewRectangleCurrent.Width * GameBase.WindowManager.Ratio,
                                                         ViewRectangleCurrent.Height * GameBase.WindowManager.Ratio);
                }

                ClipRectangle = new Rectangle((int)ViewRectangleScaled.X, (int)ViewRectangleScaled.Y, (int)Math.Ceiling(ViewRectangleScaled.Width), (int)Math.Ceiling(ViewRectangleScaled.Height));

                if (spriteListCount == 0 && !ForwardPlayOptimisations)
                {
                    return(false);
                }

                if (Alpha < 0.01f || Bypass)
                {
                    for (int m = 0; m < spriteListCount; m++)
                    {
                        SpriteList[m].IsVisible = false;
                    }
                    return(false);
                }

                LastFrameRendered = GameBase.TotalFramesRendered;

                if (BlacknessTarget >= 0)
                {
                    if (BlacknessTarget > Blackness)
                    {
                        Blackness = Math.Min(BlacknessTarget, Blackness + 0.018f * (float)GameBase.FrameRatio);
                    }
                    else if (BlacknessTarget < Blackness)
                    {
                        Blackness = Math.Max(BlacknessTarget, Blackness - 0.018f * (float)GameBase.FrameRatio);
                    }
                }

                int gameTime  = GameBase.Time;
                int audioTime = AudioEngine.Time;

                if (ForwardPlayOptimisations)
                {
                    while (forwardPlayQueue.Count > 0)
                    {
                        pDrawable i = forwardPlayQueue.Peek();
                        if (i.Transformations.Count > 0 && i.Transformations[0].Time1 > (i.Clock == Clocks.Game ? gameTime : audioTime))
                        {
                            break;
                        }

                        if (i.Transformations.Count == 0)
                        {
                            forwardPlayQueue.Dequeue().Dispose();
                            continue;
                        }

                        Add(forwardPlayQueue.Dequeue());
                        spriteListCount++;
                    }

                    if (AudioEngine.SeekedBackwards)
                    {
                        //if we are seeking backwards, re-add any previousyl removed items.
                        while (forwardPlayPast.Count > 0)
                        {
                            pDrawable i = forwardPlayPast.Peek();
                            if (i.Transformations.Count > 0)
                            {
                                int lastTransform = i.Transformations[i.Transformations.Count - 1].Time2;
                                if (lastTransform < audioTime)
                                {
                                    if (audioTime - lastTransform > 5000)
                                    {
                                        break; //allowance for out-of-order additions to this queue.
                                    }
                                }
                            }

                            i = forwardPlayPast.Pop();

                            //if (i.Clock != Clocks.AudioOnce)
                            {
                                Add(i);
                                spriteListCount++;
                            }
                        }
                    }
                }

                startBatch();

#if !DEBUG
                try
                {
#endif
                bool firstDraw = true;

                //Keep track of the OGL rectangle
                Rectangle currentClipRectangle = Masking ? ClipRectangle : OsuGlControl.ViewportZeroBased;

                //In most cases we won't be clipping more than at a spritemanager level
                //so we can save on rectangle copies/ogl calls by resetting the initial scissor rectangle here
                OsuGlControl.ResetScissor(new System.Drawing.Rectangle(OsuGlControl.Viewport.Left + currentClipRectangle.Left, OsuGlControl.Viewport.Top + GameBase.WindowManager.Height - currentClipRectangle.Bottom, currentClipRectangle.Width, currentClipRectangle.Height));

                if (SpriteBatch != null)
                {
                    SpriteBatch.ResetCounters();
                }

                for (int m = 0; m < spriteListCount; m++)
                {
                    pDrawable s = SpriteList[m];

                    if (s.Bypass)
                    {
                        continue;
                    }

#if DEBUG
                    TotalSprites++;
#endif

                    switch (s.Update())
                    {
                    case UpdateResult.Discard:
                        SpriteList.RemoveAt(m--);
                        spriteListCount--;

                        if (ForwardPlayOptimisations && s.Clock != Clocks.Game && AllowRewind)
                        {
                            forwardPlayPast.Push(s);
                        }
                        else
                        {
                            s.Dispose();
                        }
                        break;

                    case UpdateResult.NotVisible:
                        break;

                    case UpdateResult.Visible:
#if DEBUG
                        TotalSpritesVisible++;
#endif

                        if (!s.UsesSpriteBatch)
                        {
                            endBatch();
                        }

                        if (currentClipRectangle != s.ClipRectangleScaled)
                        {
                            SpriteBatch.Draw();
                            currentClipRectangle = s.ClipRectangleScaled;
                            OsuGlControl.ResetScissor(new System.Drawing.Rectangle(OsuGlControl.Viewport.Left + currentClipRectangle.Left, OsuGlControl.Viewport.Top + GameBase.WindowManager.Height - currentClipRectangle.Bottom, currentClipRectangle.Width, currentClipRectangle.Height));
                        }

                        s.Draw();
                        firstDraw = false;
                        break;
                    }
                }

                if (hasBegun)
                {
                    //there's an occasional case where blending mode is transferred outside of SpriteBatches (DirectX only).
                    //this is a safety call to reset to alpha blending.
                    SetBlending(false);
                }

                endBatch(true);

                OsuGlControl.ResetScissor();
#if !DEBUG
                exceptionCount = 0;
            }
            catch (Exception e)
            {
                /* TODO: Figure out why dialog popups are causing XNA exceptions
                 * See https://gist.github.com/324f5de475b438f48416. */

                try
                {
                    endBatch(true);
                }
                catch { }

                if (!(e is InvalidOperationException) || ++exceptionCount > 1)
                {
                    throw;
                }
            }
#endif
            }


            return(true);
        }