public override void Draw() { if (Alpha <= 0 || Progress == 0) return; Progress = (float)Math.Min(Progress, 1.0); try { float endAngle = (float)(Progress * (2 * Math.PI) + startAngle); float scaledRadius = Radius * GameBase.WindowManager.Ratio; Vector2 scaledPosition = Position * GameBase.WindowManager.Ratio; float angle1, angle2; if (endAngle < startAngle) { angle1 = endAngle; angle2 = startAngle; } else { angle1 = startAngle; angle2 = endAngle; } if (angle2 > angle1) { OsuGlControl.ColourShader2D.Begin(); if (vertexBatch == null) vertexBatch = new LinearBatch<Vertex2d>(amountPoints + 2, 1, BeginMode.TriangleFan); vertexBatch.Add(new Vertex2d() { Position = scaledPosition, Colour = this.Colour }); Vector2 offset; for (float a = angle1; a < angle2; a += da) { offset = new Vector2((float)Math.Cos(a), (float)Math.Sin(a)) * scaledRadius; vertexBatch.Add(new Vertex2d() { Position = scaledPosition + offset, Colour = this.Colour }); } offset = new Vector2((float)Math.Cos(angle2), (float)Math.Sin(angle2)) * scaledRadius; vertexBatch.Add(new Vertex2d() { Position = scaledPosition + offset, Colour = this.Colour }); vertexBatch.Draw(); OsuGlControl.ColourShader2D.End(); } } catch (InvalidOperationException) { } }
/// <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); }
/// <summary> /// Draw a list of Lines. /// </summary> /// <remarks> /// Set globalRadius = 0 to use the radius stored in each Line. /// Set globalColor to Color.TransparentBlack to use the color stored in each Line. /// </remarks> internal void Draw(List <Line> lineList, float globalRadius, Color globalColour, float time, string techniqueName, bool roundEdges, bool roundEndsOnly = false, int res = MAXRES) { OsuGlControl.ColourShader2D.Begin(); if (res > MAXRES) { res = MAXRES; } bool noBlur = techniqueName == @"NoBlur"; bool noGradient = techniqueName == DEFAULT_TECHNIQUE_NG; int lineCount = lineList.Count; for (int i = 0; i < lineCount; ++i) { Line l = lineList[i]; ColouredLine cl = l as ColouredLine; Vector2 direction = Vector2.Normalize(l.p2 - l.p1); Vector2 cross = new Vector2(globalRadius * direction.Y, -globalRadius * direction.X); if (cl != null && cl.colour != Color.White) { globalColour = cl.colour; } Vector2 p1n = l.p1 + cross; Vector2 p1m = l.p1 - cross; Vector2 p2n = l.p2 - cross; Vector2 p2m = l.p2 + cross; quadBatch.Add(new Vertex2d() { Position = p1n, Colour = globalColour }); quadBatch.Add(new Vertex2d() { Position = p2m, Colour = globalColour }); Color colour = globalColour; if (!noBlur) { if (!noGradient) { colour = new Color(globalColour.R, globalColour.G, globalColour.B, (byte)(Math.Max(0, globalColour.A - 30))); } quadBatch.Add(new Vertex2d() { Position = l.p2, Colour = colour }); quadBatch.Add(new Vertex2d() { Position = l.p1, Colour = colour }); quadBatch.Add(new Vertex2d() { Position = l.p1, Colour = colour }); quadBatch.Add(new Vertex2d() { Position = l.p2, Colour = colour }); } quadBatch.Add(new Vertex2d() { Position = p2n, Colour = globalColour }); quadBatch.Add(new Vertex2d() { Position = p1m, Colour = globalColour }); float theta = l.theta; if (roundEdges) { if (roundEndsOnly) { if (i == 0) { HalfCircle(l.p1, globalRadius, (float)(theta + Math.PI * 5 / 2), (float)Math.PI, globalColour, !noGradient && !noBlur, res); } if (i == lineCount - 1) { HalfCircle(l.p2, globalRadius, (float)(theta + Math.PI * 3 / 2), (float)Math.PI, globalColour, !noGradient && !noBlur, res); } if (i < lineCount - 1) { float theta2 = lineList[i + 1].theta; float startAngle; float arcLength; if (theta < theta2 - 0.01f) { arcLength = theta2 - theta; startAngle = (float)(theta + Math.PI * 3 / 2); } else if (theta2 < theta - 0.01f) { arcLength = theta - theta2; startAngle = (float)(theta2 + Math.PI * 5 / 2); } else { continue; } HalfCircle(l.p2, globalRadius, startAngle, arcLength, globalColour, !noGradient && !noBlur, 2); } } else { HalfCircle(l.p1, globalRadius, (float)(theta + Math.PI * 5 / 2), (float)Math.PI, globalColour, !noGradient && !noBlur, res); HalfCircle(l.p2, globalRadius, (float)(theta + Math.PI * 3 / 2), (float)Math.PI, globalColour, !noGradient && !noBlur, res); } } } quadBatch.Draw(); triangleFanBatch.Draw(); OsuGlControl.ColourShader2D.End(); }
/// <summary> /// End is called once all the primitives have been drawn using AddVertex. /// </summary> internal void End() { vertexBatch.Draw(); OsuGlControl.ColourShader2D.End(); }
/// <summary> /// Render a gradient into a 256x1 texture. /// </summary> private TextureGl RenderSliderTexture(Color shadow, Color border, Color InnerColour, Color OuterColour, float aa_width) { using (RenderTarget2D target = new RenderTarget2D(TEX_WIDTH, 1)) { target.Bind(); GL.Disable(EnableCap.DepthTest); GL.Disable(EnableCap.Blend); GL.ClearColor(0.859f, 0.439f, 0.576f, 1.0f); GL.Clear(ClearBufferMask.ColorBufferBit); GL.ClearColor(0, 0, 0, 0); OsuGlControl.ColourShader2D.Properties[@"g_ProjMatrix"] = OpenTK.Matrix4.CreateOrthographicOffCenter(0.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f); OsuGlControl.ColourShader2D.Begin(); lineBatch.Add(new Vertex2d() { Position = new Vector2(-0.5f, 0.0f), Colour = Color.TransparentBlack }); lineBatch.Add(new Vertex2d() { Position = new Vector2(0.0f, 0.0f), Colour = Color.TransparentBlack }); lineBatch.Add(new Vertex2d() { Position = new Vector2(0.078125f - aa_width, 0.0f), Colour = shadow }); lineBatch.Add(new Vertex2d() { Position = new Vector2(0.078125f + aa_width, 0.0f), Colour = border }); lineBatch.Add(new Vertex2d() { Position = new Vector2(0.1875f - aa_width, 0.0f), Colour = border }); lineBatch.Add(new Vertex2d() { Position = new Vector2(0.1875f + aa_width, 0.0f), Colour = OuterColour }); lineBatch.Add(new Vertex2d() { Position = new Vector2(1.0f, 0.0f), Colour = InnerColour }); lineBatch.Add(new Vertex2d() { Position = new Vector2(1.5f, 0.0f), Colour = InnerColour }); lineBatch.Draw(); OsuGlControl.ColourShader2D.End(); OsuGlControl.ColourShader2D.Properties[@"g_ProjMatrix"] = OsuGlControl.ProjectionMatrix; if (!OsuGlControl.CanUseFBO) { //We must re-clear the backbuffer target.Unbind(); GL.Clear(ClearBufferMask.ColorBufferBit); } GL.Enable(EnableCap.Blend); return(target.Texture); } }