add MultiShape
This commit is contained in:
parent
24608a6068
commit
5f657bafef
93
graphics.go
93
graphics.go
|
@ -173,6 +173,99 @@ func (s *Shape) Draw(t ...Transform) {
|
|||
})
|
||||
}
|
||||
|
||||
// MultiShape is a shape composed of several other shapes. These shapes cannot be modifies after combined into a multishape.
|
||||
//
|
||||
// Using a multishape can greatly increase drawing performance. However, it's only usable when the relative transformations
|
||||
// of the shapes don't change (e.g. static blocks in a level).
|
||||
//
|
||||
// All shapes in a multishape must share the same texture (or use no texture).
|
||||
type MultiShape struct {
|
||||
*Shape
|
||||
}
|
||||
|
||||
// NewMultiShape creates a new multishape from several other shapes. These shapes are automatically deleted after creating a multishape.
|
||||
//
|
||||
// If two of the supplied shapes have different pictures, this function panics.
|
||||
func NewMultiShape(parent pixelgl.Doer, shapes ...*Shape) *MultiShape {
|
||||
var picture Picture
|
||||
for _, shape := range shapes {
|
||||
if picture.IsNil() {
|
||||
picture = shape.Picture()
|
||||
} else {
|
||||
if shape.Picture().IsNil() && shape.Picture() != picture {
|
||||
panic(errors.New("failed to create multishape: shapes have different pictures"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var va *pixelgl.VertexArray
|
||||
|
||||
var (
|
||||
vertexNum int
|
||||
indices []int
|
||||
)
|
||||
offset := 0
|
||||
for _, shape := range shapes {
|
||||
vertexNum += shape.VertexArray().VertexNum()
|
||||
|
||||
for _, i := range shape.va.Indices() {
|
||||
indices = append(indices, offset+i)
|
||||
}
|
||||
offset += shape.VertexArray().VertexNum()
|
||||
}
|
||||
|
||||
parent.Do(func(ctx pixelgl.Context) {
|
||||
var err error
|
||||
va, err = pixelgl.NewVertexArray(
|
||||
pixelgl.ContextHolder{Context: ctx},
|
||||
ctx.Shader().VertexFormat(),
|
||||
vertexNum,
|
||||
indices,
|
||||
)
|
||||
if err != nil {
|
||||
panic(errors.Wrap(err, "failed to create multishape"))
|
||||
}
|
||||
})
|
||||
|
||||
offset = 0
|
||||
for _, shape := range shapes {
|
||||
for i := 0; i < shape.VertexArray().VertexNum(); i++ {
|
||||
for name, typ := range va.VertexFormat() {
|
||||
attr := pixelgl.Attr{Name: name, Type: typ}
|
||||
value, ok := shape.VertexArray().VertexAttr(i, attr)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
va.SetVertexAttr(offset+i, attr, value)
|
||||
}
|
||||
|
||||
if position, ok := shape.VertexArray().VertexAttr(i, positionVec2); ok {
|
||||
position := position.(mgl32.Vec2)
|
||||
position = shape.Transform().Mat3().Mul3x1(mgl32.Vec3{position.X(), position.Y(), 1}).Vec2()
|
||||
va.SetVertexAttr(offset+i, positionVec2, position)
|
||||
}
|
||||
if color, ok := shape.VertexArray().VertexAttr(i, colorVec4); ok {
|
||||
color := color.(mgl32.Vec4)
|
||||
r, g, b, a := colorToRGBA(shape.Color())
|
||||
color = mgl32.Vec4{
|
||||
color[0] * r,
|
||||
color[1] * g,
|
||||
color[2] * b,
|
||||
color[3] * a,
|
||||
}
|
||||
va.SetVertexAttr(offset+i, colorVec4, color)
|
||||
}
|
||||
}
|
||||
offset += shape.VertexArray().VertexNum()
|
||||
}
|
||||
|
||||
for _, shape := range shapes {
|
||||
shape.Delete()
|
||||
}
|
||||
|
||||
return &MultiShape{NewShape(parent, picture, color.White, Position(0), va)}
|
||||
}
|
||||
|
||||
// Sprite is a picture that can be drawn on the screen. Optionally it can be color masked or tranformed.
|
||||
//
|
||||
// Usually, you only transform objects when you're drawing them (by passing transforms to the Draw method).
|
||||
|
|
Loading…
Reference in New Issue