Skip to content

Commit

Permalink
Move Circle to GL shader
Browse files Browse the repository at this point in the history
  • Loading branch information
andydotxyz committed Sep 18, 2023
1 parent 998790f commit c76893c
Showing 1 changed file with 77 additions and 4 deletions.
81 changes: 77 additions & 4 deletions internal/painter/gl/draw.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,64 @@ func (p *painter) defineVertexArray(prog Program, name string, size, stride, off
func (p *painter) drawCircle(circle *canvas.Circle, pos fyne.Position, frame fyne.Size) {
p.drawTextureWithDetails(circle, p.newGlCircleTexture, pos, circle.Size(), frame, canvas.ImageFillStretch,
1.0, paint.VectorPad(circle))

radius := circle.Size().Width / 2
if circle.Size().Height < circle.Size().Width {
radius = circle.Size().Height / 2
}
program := p.roundRectangleProgram

// Vertex: BEG
bounds, points := p.vecSquareCoords(pos, circle, frame)
p.ctx.UseProgram(program)
vbo := p.createBuffer(points)
p.defineVertexArray(program, "vert", 2, 4, 0)
p.defineVertexArray(program, "normal", 2, 4, 2)

p.ctx.BlendFunc(srcAlpha, oneMinusSrcAlpha)
p.logError()
// Vertex: END

// Fragment: BEG
frameSizeUniform := p.ctx.GetUniformLocation(program, "frame_size")
frameWidthScaled, frameHeightScaled := p.scaleFrameSize(frame)
p.ctx.Uniform2f(frameSizeUniform, frameWidthScaled, frameHeightScaled)

rectCoordsUniform := p.ctx.GetUniformLocation(program, "rect_coords")
x1Scaled, x2Scaled, y1Scaled, y2Scaled := p.scaleRectCoords(bounds[0], bounds[2], bounds[1], bounds[3])
p.ctx.Uniform4f(rectCoordsUniform, x1Scaled, x2Scaled, y1Scaled, y2Scaled)

strokeWidthScaled := roundToPixel(circle.StrokeWidth*p.pixScale, 1.0)
strokeUniform := p.ctx.GetUniformLocation(program, "stroke_width_half")
p.ctx.Uniform1f(strokeUniform, strokeWidthScaled*0.5)

rectSizeUniform := p.ctx.GetUniformLocation(program, "rect_size_half")
rectSizeWidthScaled := x2Scaled - x1Scaled - strokeWidthScaled
rectSizeHeightScaled := y2Scaled - y1Scaled - strokeWidthScaled
p.ctx.Uniform2f(rectSizeUniform, rectSizeWidthScaled*0.5, rectSizeHeightScaled*0.5)

radiusUniform := p.ctx.GetUniformLocation(program, "radius")
radiusScaled := roundToPixel(radius*p.pixScale, 1.0)
p.ctx.Uniform1f(radiusUniform, radiusScaled)

var r, g, b, a float32
fillColorUniform := p.ctx.GetUniformLocation(program, "fill_color")
r, g, b, a = getFragmentColor(circle.FillColor)
p.ctx.Uniform4f(fillColorUniform, r, g, b, a)

strokeColorUniform := p.ctx.GetUniformLocation(program, "stroke_color")
strokeColor := circle.StrokeColor
if strokeColor == nil {
strokeColor = color.Transparent
}
r, g, b, a = getFragmentColor(strokeColor)
p.ctx.Uniform4f(strokeColorUniform, r, g, b, a)
p.logError()
// Fragment: END

p.ctx.DrawArrays(triangleStrip, 0, 4)
p.logError()
p.freeBuffer(vbo)
}

func (p *painter) drawGradient(o fyne.CanvasObject, texCreator func(fyne.CanvasObject) Texture, pos fyne.Position, frame fyne.Size) {
Expand Down Expand Up @@ -338,15 +396,19 @@ func rectInnerCoords(size fyne.Size, pos fyne.Position, fill canvas.ImageFill, a
}

func (p *painter) vecRectCoords(pos fyne.Position, rect *canvas.Rectangle, frame fyne.Size) ([4]float32, []float32) {
return p.vecRectCoordsWithPad(pos, rect, frame, 0, 0)
}

func (p *painter) vecRectCoordsWithPad(pos fyne.Position, rect fyne.CanvasObject, frame fyne.Size, xPad, yPad float32) ([4]float32, []float32) {
size := rect.Size()
pos1 := rect.Position()

xPosDiff := pos.X - pos1.X
yPosDiff := pos.Y - pos1.Y
xPosDiff := pos.X - pos1.X + xPad
yPosDiff := pos.Y - pos1.Y + yPad
pos1.X = roundToPixel(pos1.X+xPosDiff, p.pixScale)
pos1.Y = roundToPixel(pos1.Y+yPosDiff, p.pixScale)
size.Width = roundToPixel(size.Width, p.pixScale)
size.Height = roundToPixel(size.Height, p.pixScale)
size.Width = roundToPixel(size.Width-2*xPad, p.pixScale)
size.Height = roundToPixel(size.Height-2*yPad, p.pixScale)

x1Pos := pos1.X
x1Norm := -1 + x1Pos*2/frame.Width
Expand All @@ -367,6 +429,17 @@ func (p *painter) vecRectCoords(pos fyne.Position, rect *canvas.Rectangle, frame
return [4]float32{x1Pos, y1Pos, x2Pos, y2Pos}, coords
}

func (p *painter) vecSquareCoords(pos fyne.Position, rect fyne.CanvasObject, frame fyne.Size) ([4]float32, []float32) {
xPad, yPad := float32(0), float32(0)
if rect.Size().Width > rect.Size().Height {
xPad = (rect.Size().Width - rect.Size().Height) / 2
} else {
yPad = (rect.Size().Height - rect.Size().Width) / 2
}

return p.vecRectCoordsWithPad(pos, rect, frame, xPad, yPad)
}

func roundToPixel(v float32, pixScale float32) float32 {
if pixScale == 1.0 {
return float32(math.Round(float64(v)))
Expand Down

0 comments on commit c76893c

Please sign in to comment.