add ellipse shape

This commit is contained in:
faiface 2016-12-03 19:51:43 +01:00
parent ffc9a1a0ff
commit 23fd33ac75
1 changed files with 137 additions and 4 deletions

View File

@ -2,6 +2,7 @@ package pixel
import (
"image/color"
"math"
"github.com/faiface/pixel/pixelgl"
"github.com/go-gl/mathgl/mgl32"
@ -45,7 +46,7 @@ type PolygonColor struct {
}
// NewPolygonColor creates a new polygon shape filled with a single color. Parent is an object that this shape belongs to,
// such as a window, or a graphical effect.
// such as a window, or a graphics effect.
func NewPolygonColor(parent pixelgl.Doer, c color.Color, points ...Vec) *PolygonColor {
pc := &PolygonColor{
parent: parent,
@ -59,14 +60,31 @@ func NewPolygonColor(parent pixelgl.Doer, c color.Color, points ...Vec) *Polygon
})
var err error
pc.va, err = pixelgl.NewVertexArray(parent, format, pixelgl.TriangleFanDrawMode, pixelgl.DynamicUsage, len(points))
pc.va, err = pixelgl.NewVertexArray(
parent,
format,
pixelgl.TriangleFanDrawMode,
pixelgl.DynamicUsage,
len(points),
)
if err != nil {
panic(errors.Wrap(err, "failed to create polygon"))
}
for i, p := range points {
pc.va.SetVertexAttributeVec2(i, pixelgl.Position, mgl32.Vec2{float32(p.X()), float32(p.Y())})
pc.va.SetVertexAttributeVec4(i, pixelgl.Color, mgl32.Vec4{1, 1, 1, 1})
pc.va.SetVertexAttributeVec2(
i,
pixelgl.Position,
mgl32.Vec2{
float32(p.X()),
float32(p.Y()),
},
)
pc.va.SetVertexAttributeVec4(
i,
pixelgl.Color,
mgl32.Vec4{1, 1, 1, 1},
)
}
return pc
@ -126,3 +144,118 @@ func (pc *PolygonColor) Draw(t ...Transform) {
func (pc *PolygonColor) Delete() {
pc.va.Delete()
}
// EllipseColor is an ellipse shape filled with a single color.
type EllipseColor struct {
parent pixelgl.Doer
color color.Color
radius Vec
fill float64
va *pixelgl.VertexArray
}
// NewEllipseColor creates a new ellipse shape filled with a single color. Parent is an object that this shape belongs to,
// such as a window, or a graphics effect. Fill should be a number between 0 and 1 which specifies how much of the ellipse will
// be filled (from the outside). The value of 1 means that the whole ellipse is filled. The value of 0 means that none of the
// ellipse is filled (which makes the ellipse invisible).
func NewEllipseColor(parent pixelgl.Doer, c color.Color, radius Vec, fill float64) *EllipseColor {
const n = 256
ec := &EllipseColor{
parent: parent,
color: c,
radius: radius,
fill: fill,
}
var format pixelgl.VertexFormat
parent.Do(func(ctx pixelgl.Context) {
format = ctx.Shader().VertexFormat()
})
var err error
ec.va, err = pixelgl.NewVertexArray(
parent,
format,
pixelgl.TriangleStripDrawMode,
pixelgl.DynamicUsage,
(n+1)*2,
)
if err != nil {
panic(errors.Wrap(err, "failed to create circle"))
}
for k := 0; k < n+1; k++ {
i, j := k*2, k*2+1
angle := math.Pi * 2 * float64(k%n) / n
ec.va.SetVertexAttributeVec2(
i,
pixelgl.Position,
mgl32.Vec2{
float32(math.Cos(angle)),
float32(math.Sin(angle)),
},
)
ec.va.SetVertexAttributeVec4(
i,
pixelgl.Color,
mgl32.Vec4{1, 1, 1, 1},
)
ec.va.SetVertexAttributeVec2(
j,
pixelgl.Position,
mgl32.Vec2{
float32(math.Cos(angle) * (1 - fill)),
float32(math.Sin(angle) * (1 - fill)),
},
)
ec.va.SetVertexAttributeVec4(
j,
pixelgl.Color,
mgl32.Vec4{1, 1, 1, 1},
)
}
return ec
}
// SetColor changes the color of an ellipse.
func (ec *EllipseColor) SetColor(c color.Color) {
ec.color = c
}
// Color returns the current color of an ellipse.
func (ec *EllipseColor) Color() color.Color {
return ec.color
}
// SetRadius sets the radius (which can be different in X and Y axis) of an ellipse.
func (ec *EllipseColor) SetRadius(radius Vec) {
ec.radius = radius
}
// Radius returns the current radius of an ellipse.
func (ec *EllipseColor) Radius() Vec {
return ec.radius
}
// Draw dras an ellipse transformed by the supplied transforms applied in the reverse order.
func (ec *EllipseColor) Draw(t ...Transform) {
mat := mgl32.Ident3()
for i := range t {
mat = mat.Mul3(t[i].Mat3())
}
mat = mat.Mul3(mgl32.Scale2D(float32(ec.radius.X()), float32(ec.radius.Y())))
var shader *pixelgl.Shader
ec.parent.Do(func(ctx pixelgl.Context) {
shader = ctx.Shader()
})
r, g, b, a := colorToRGBA(ec.color)
shader.SetUniformVec4(pixelgl.MaskColor, mgl32.Vec4{r, g, b, a})
shader.SetUniformMat3(pixelgl.Transform, mat)
shader.SetUniformInt(pixelgl.IsTexture, 0)
ec.va.Draw()
}