func (e *engine) render(n *sprite.Node, t clock.Time) { if n.EngineFields.Index == 0 { panic("portable: sprite.Node not registered") } if n.Arranger != nil { n.Arranger.Arrange(e, n, t) } // Push absTransforms. // TODO: cache absolute transforms and use EngineFields.Dirty? rel := &e.nodes[n.EngineFields.Index].relTransform m := f32.Affine{} m.Mul(&e.absTransforms[len(e.absTransforms)-1], rel) e.absTransforms = append(e.absTransforms, m) if x := n.EngineFields.SubTex; x.T != nil { // Affine transforms work in geom.Pt, which is entirely // independent of the number of pixels in a texture. A texture // of any image.Rectangle bounds rendered with // // Affine{{1, 0, 0}, {0, 1, 0}} // // should have the dimensions (1pt, 1pt). To do this we divide // by the pixel width and height, reducing the texture to // (1px, 1px) of the destination image. Multiplying by // geom.PixelsPerPt, done in Render above, makes it (1pt, 1pt). dx, dy := x.R.Dx(), x.R.Dy() if dx > 0 && dy > 0 { m.Scale(&m, 1/float32(dx), 1/float32(dy)) m.Inverse(&m) // See the documentation on the affine function. affine(e.dst, x.T.(*texture).m, x.R, nil, &m, draw.Over) } } for c := n.FirstChild; c != nil; c = c.NextSibling { e.render(c, t) } // Pop absTransforms. e.absTransforms = e.absTransforms[:len(e.absTransforms)-1] }
func (e *engine) render(n *sprite.Node, t clock.Time) { if n.EngineFields.Index == 0 { panic("glsprite: sprite.Node not registered") } if n.Arranger != nil { n.Arranger.Arrange(e, n, t) } // Push absTransforms. // TODO: cache absolute transforms and use EngineFields.Dirty? rel := &e.nodes[n.EngineFields.Index].relTransform m := f32.Affine{} m.Mul(&e.absTransforms[len(e.absTransforms)-1], rel) e.absTransforms = append(e.absTransforms, m) if x := n.EngineFields.SubTex; x.T != nil { x.T.(*texture).glImage.Draw( geom.Point{ geom.Pt(m[0][2]), geom.Pt(m[1][2]), }, geom.Point{ geom.Pt(m[0][2] + m[0][0]), geom.Pt(m[1][2] + m[1][0]), }, geom.Point{ geom.Pt(m[0][2] + m[0][1]), geom.Pt(m[1][2] + m[1][1]), }, x.R, ) } for c := n.FirstChild; c != nil; c = c.NextSibling { e.render(c, t) } // Pop absTransforms. e.absTransforms = e.absTransforms[:len(e.absTransforms)-1] }