From d16037c9830d9608ef9d255acde3c4f2e8f66d69 Mon Sep 17 00:00:00 2001 From: faiface <faiface@ksp.sk> Date: Sat, 3 Dec 2016 16:25:41 +0100 Subject: [PATCH] add Drawer interface and PolygonColor shape --- graphics.go | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 graphics.go diff --git a/graphics.go b/graphics.go new file mode 100644 index 0000000..3807964 --- /dev/null +++ b/graphics.go @@ -0,0 +1,110 @@ +package pixel + +import ( + "image/color" + + "github.com/faiface/pixel/pixelgl" + "github.com/go-gl/mathgl/mgl32" + "github.com/pkg/errors" +) + +// Drawer is anything that can be drawn. It's by no means a drawer inside your table. +// +// Drawer consists of a single method: Draw. Draw methods takes any number of Transform arguments. It applies these +// transforms in the reverse order and finally draws something transformed by these transforms. +// +// Example: +// +// // object is a drawer +// object.Draw(pixel.Position(pixel.V(100, 100).Rotate(math.Pi / 2))) +// camera := pixel.Camera(pixel.V(0, 0), pixel.V(500, 500), pixel.V(window.Size())) +// object.Draw(camera, pixel.Position(0).Scale(0.5)) +type Drawer interface { + Draw(t ...Transform) +} + +// PolygonColor is a polygon shape filled with a single color. +type PolygonColor struct { + parent pixelgl.Doer + color color.Color + points []Vec + va *pixelgl.VertexArray +} + +// 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. +func NewPolygonColor(parent pixelgl.Doer, c color.Color, points ...Vec) *PolygonColor { + pc := &PolygonColor{ + parent: parent, + color: c, + points: points, + } + + var format pixelgl.VertexFormat + parent.Do(func(ctx pixelgl.Context) { + format = ctx.Shader().VertexFormat() + }) + + var err error + 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}) + } + + return pc +} + +// Count returns the number of points in a polygon. +func (pc *PolygonColor) Count() int { + return len(pc.points) +} + +// SetColor changes the color of a polygon to c. +func (pc *PolygonColor) SetColor(c color.Color) { + pc.color = c +} + +// Color returns the current color of a polygon. +func (pc *PolygonColor) Color() color.Color { + return pc.color +} + +// SetPoint changes the position of a point in a polygon. +// +// If the index is out of range, this function panics. +func (pc *PolygonColor) SetPoint(i int, point Vec) { + pc.points[i] = point + pc.va.SetVertexAttributeVec2(i, pixelgl.Position, mgl32.Vec2{float32(point.X()), float32(point.Y())}) +} + +// Point returns the position of a point in a polygon. +// +// If the index is out of range, this function panics. +func (pc *PolygonColor) Point(i int) Vec { + return pc.points[i] +} + +// Draw draws a polygon transformed by the supplied transforms applied in the reverse order. +func (pc *PolygonColor) Draw(t ...Transform) { + mat := mgl32.Ident3() + for i := range t { + mat = mat.Mul3(t[i].Mat3()) + } + + var shader *pixelgl.Shader + pc.parent.Do(func(ctx pixelgl.Context) { + shader = ctx.Shader() + }) + + r, g, b, a := colorToRGBA(pc.color) + shader.SetUniformVec4(pixelgl.MaskColor, mgl32.Vec4{r, g, b, a}) + shader.SetUniformMat3(pixelgl.Transform, mat) + shader.SetUniformInt(pixelgl.IsTexture, 0) + + pc.va.Draw() +} -- GitLab