From c78c4052d0ba7bba7642fbd190a716071d2ae855 Mon Sep 17 00:00:00 2001 From: Sander Schobers Date: Sun, 17 May 2020 11:12:45 +0200 Subject: [PATCH] Refactored DrawTexture on Renderer to favor rendering using destination rectangle instead of a point. --- allg5ui/renderer.go | 31 ++++++++++++++++++++++++------- sdlui/renderer.go | 39 +++++++++++++++++++++++++++------------ ui/buffer.go | 2 +- ui/button.go | 4 ++-- ui/checkbox.go | 5 +++-- ui/drawoptions.go | 3 +-- ui/renderer.go | 6 ++++-- ui/slider.go | 2 +- 8 files changed, 63 insertions(+), 29 deletions(-) diff --git a/allg5ui/renderer.go b/allg5ui/renderer.go index a3c4df7..92b08b3 100644 --- a/allg5ui/renderer.go +++ b/allg5ui/renderer.go @@ -220,21 +220,38 @@ func (r *Renderer) DefaultTarget() ui.Texture { func (r *Renderer) Display() *allg5.Display { return r.disp } -func (r *Renderer) DrawTexture(texture ui.Texture, p geom.PointF32) { - bmp := r.mustGetBitmap(texture) - x, y := snap(p) - bmp.Draw(x, y) +func (r *Renderer) DrawTexture(texture ui.Texture, p geom.RectangleF32) { + r.DrawTextureOptions(texture, p, ui.DrawOptions{}) } -func (r *Renderer) DrawTextureOptions(texture ui.Texture, p geom.PointF32, opts ui.DrawOptions) { +func (r *Renderer) DrawTextureOptions(texture ui.Texture, p geom.RectangleF32, opts ui.DrawOptions) { bmp := r.mustGetBitmap(texture) + x, y := snap(p.Min) var o allg5.DrawOptions if opts.Tint != nil { tint := newColor(opts.Tint) o.Tint = &tint } - if opts.Scale != nil { - o.Scale = &allg5.Scale{Horizontal: opts.Scale.X, Vertical: opts.Scale.Y} + w, h := p.Dx(), p.Dy() + bmpW, bmpH := float32(bmp.Width()), float32(bmp.Height()) + if w != bmpW || h != bmpH { + o.Scale = &allg5.Scale{Horizontal: w / bmpW, Vertical: h / bmpH} + } + bmp.DrawOptions(x, y, o) +} + +func (r *Renderer) DrawTexturePoint(texture ui.Texture, p geom.PointF32) { + bmp := r.mustGetBitmap(texture) + x, y := snap(p) + bmp.Draw(x, y) +} + +func (r *Renderer) DrawTexturePointOptions(texture ui.Texture, p geom.PointF32, opts ui.DrawOptions) { + bmp := r.mustGetBitmap(texture) + var o allg5.DrawOptions + if opts.Tint != nil { + tint := newColor(opts.Tint) + o.Tint = &tint } x, y := snap(p) bmp.DrawOptions(x, y, o) diff --git a/sdlui/renderer.go b/sdlui/renderer.go index bbdceac..9dafdbb 100644 --- a/sdlui/renderer.go +++ b/sdlui/renderer.go @@ -285,28 +285,43 @@ func (r *Renderer) CreateTextureTarget(w, h float32) (ui.Texture, error) { func (r *Renderer) DefaultTarget() ui.Texture { return r } -func (r *Renderer) DrawTexture(t ui.Texture, p geom.PointF32) { - r.DrawTextureOptions(t, p, ui.DrawOptions{}) +func (r *Renderer) drawTexture(t sdlTexture, src, dst sdl.Rect, opts ui.DrawOptions) { + if opts.Tint != nil { + t.SetColor(opts.Tint) + } + r.renderer.Copy(t.Native(), &src, &dst) } -func (r *Renderer) DrawTextureOptions(t ui.Texture, p geom.PointF32, opts ui.DrawOptions) { +func (r *Renderer) DrawTexture(t ui.Texture, dst geom.RectangleF32) { + r.DrawTextureOptions(t, dst, ui.DrawOptions{}) +} + +func (r *Renderer) DrawTextureOptions(t ui.Texture, dst geom.RectangleF32, opts ui.DrawOptions) { texture, ok := t.(sdlTexture) if !ok { return } - if opts.Tint != nil { - texture.SetColor(opts.Tint) - } width, height, err := texture.Size() if err != nil { return } - dst := RectPtr(int32(p.X), int32(p.Y), width, height) - if opts.Scale != nil { - dst.W = int32(float32(width) * opts.Scale.X) - dst.H = int32(float32(height) * opts.Scale.Y) + r.drawTexture(texture, Rect(0, 0, width, height), RectAbs(int32(dst.Min.X), int32(dst.Min.Y), int32(dst.Max.X), int32(dst.Max.Y)), opts) +} + +func (r *Renderer) DrawTexturePoint(t ui.Texture, dst geom.PointF32) { + r.DrawTexturePointOptions(t, dst, ui.DrawOptions{}) +} + +func (r *Renderer) DrawTexturePointOptions(t ui.Texture, dst geom.PointF32, opts ui.DrawOptions) { + texture, ok := t.(sdlTexture) + if !ok { + return } - r.renderer.Copy(texture.Native(), RectPtr(0, 0, width, height), dst) + width, height, err := texture.Size() + if err != nil { + return + } + r.drawTexture(texture, Rect(0, 0, width, height), Rect(int32(dst.X), int32(dst.Y), width, height), opts) } func (r *Renderer) FillRectangle(rect geom.RectangleF32, c color.Color) { @@ -401,7 +416,7 @@ func (r *Renderer) Text(font ui.Font, p geom.PointF32, color color.Color, text s } defer texture.Destroy() - r.DrawTexture(&Texture{texture}, p) + r.DrawTexturePoint(&Texture{texture}, p) } func (r *Renderer) TextAlign(font ui.Font, p geom.PointF32, color color.Color, text string, align ui.HorizontalAlignment) { diff --git a/ui/buffer.go b/ui/buffer.go index aebda26..4b4d052 100644 --- a/ui/buffer.go +++ b/ui/buffer.go @@ -36,7 +36,7 @@ func (b *Buffer) Render(ctx Context, pos geom.PointF32, fn RenderBufferFn) { renderer.RenderTo(b.texture) fn(ctx, b.size) renderer.RenderTo(currTarget) - renderer.DrawTexture(b.texture, pos) + renderer.DrawTexturePoint(b.texture, pos) } type BufferControl struct { diff --git a/ui/button.go b/ui/button.go index 053adc1..9e638ab 100644 --- a/ui/button.go +++ b/ui/button.go @@ -181,8 +181,8 @@ func (b *Button) Render(ctx Context) { if scaled == nil { // let the renderer scale scaled = icon } - scale, iconWidth := ScaleToHeight(SizeOfTexture(scaled), boundsH) - ctx.Renderer().DrawTextureOptions(scaled, geom.PtF32(pos.X, pos.Y), DrawOptions{Tint: textColor, Scale: scale}) + _, iconWidth := ScaleToHeight(SizeOfTexture(scaled), boundsH) + ctx.Renderer().DrawTextureOptions(scaled, geom.RectRelF32(pos.X, pos.Y, iconWidth, boundsH), DrawOptions{Tint: textColor}) pos.X += iconWidth + pad } if len(b.Text) != 0 { diff --git a/ui/checkbox.go b/ui/checkbox.go index b4eed2e..5a8f4c1 100644 --- a/ui/checkbox.go +++ b/ui/checkbox.go @@ -123,8 +123,9 @@ func (c *Checkbox) Render(ctx Context) { if scaledIcon == nil { // let the renderer scale scaledIcon = icon } - scale, iconWidth := ScaleToHeight(SizeOfTexture(scaledIcon), boundsH) - ctx.Renderer().DrawTextureOptions(scaledIcon, geom.PtF32(pos.X, pos.Y), DrawOptions{Tint: iconColor, Scale: scale}) + _, iconWidth := ScaleToHeight(SizeOfTexture(scaledIcon), boundsH) + rect := geom.RectRelF32(pos.X, pos.Y, iconWidth, boundsH) + ctx.Renderer().DrawTextureOptions(scaledIcon, rect, DrawOptions{Tint: iconColor}) pos.X += iconWidth + pad } if len(c.Text) != 0 { diff --git a/ui/drawoptions.go b/ui/drawoptions.go index 37834f9..bd5f925 100644 --- a/ui/drawoptions.go +++ b/ui/drawoptions.go @@ -7,8 +7,7 @@ import ( ) type DrawOptions struct { - Tint color.Color - Scale *geom.PointF32 + Tint color.Color } func ScaleToHeight(size geom.PointF32, height float32) (*geom.PointF32, float32) { diff --git a/ui/renderer.go b/ui/renderer.go index fa38353..31c4547 100644 --- a/ui/renderer.go +++ b/ui/renderer.go @@ -23,8 +23,10 @@ type Renderer interface { CreateTexturePath(path string, source bool) (Texture, error) CreateTextureTarget(w, h float32) (Texture, error) DefaultTarget() Texture - DrawTexture(t Texture, p geom.PointF32) - DrawTextureOptions(t Texture, p geom.PointF32, opts DrawOptions) + DrawTexture(t Texture, p geom.RectangleF32) + DrawTextureOptions(t Texture, p geom.RectangleF32, opts DrawOptions) + DrawTexturePoint(t Texture, p geom.PointF32) + DrawTexturePointOptions(t Texture, p geom.PointF32, opts DrawOptions) FillRectangle(r geom.RectangleF32, c color.Color) Rectangle(r geom.RectangleF32, c color.Color, thickness float32) RenderTo(Texture) diff --git a/ui/slider.go b/ui/slider.go index ef389b5..0db1194 100644 --- a/ui/slider.go +++ b/ui/slider.go @@ -179,5 +179,5 @@ func (h *sliderHandle) Render(ctx Context) { if h.IsOver() { color = ctx.Style().Palette.PrimaryLight } - ctx.Renderer().DrawTextureOptions(h.texture(ctx), h.Bounds().Min, DrawOptions{Tint: color}) + ctx.Renderer().DrawTexturePointOptions(h.texture(ctx), h.Bounds().Min, DrawOptions{Tint: color}) }