Skip to content

Commit

Permalink
replaced [2]float64 with Vec type
Browse files Browse the repository at this point in the history
  • Loading branch information
tfriedel6 committed Mar 22, 2020
1 parent cc9247c commit 804a9c2
Show file tree
Hide file tree
Showing 19 changed files with 94 additions and 124 deletions.
10 changes: 5 additions & 5 deletions backend/backendbase/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ type Backend interface {
LoadLinearGradient(data Gradient) LinearGradient
LoadRadialGradient(data Gradient) RadialGradient

Clear(pts [4][2]float64)
Fill(style *FillStyle, pts [][2]float64, canOverlap bool)
DrawImage(dimg Image, sx, sy, sw, sh float64, pts [4][2]float64, alpha float64)
FillImageMask(style *FillStyle, mask *image.Alpha, pts [4][2]float64) // pts must have four points
Clear(pts [4]Vec)
Fill(style *FillStyle, pts []Vec, canOverlap bool)
DrawImage(dimg Image, sx, sy, sw, sh float64, pts [4]Vec, alpha float64)
FillImageMask(style *FillStyle, mask *image.Alpha, pts [4]Vec) // pts must have four points

ClearClip()
Clip(pts [][2]float64)
Clip(pts []Vec)

GetImageData(x, y, w, h int) *image.RGBA
PutImageData(img *image.RGBA, x, y int)
Expand Down
3 changes: 2 additions & 1 deletion backend/goglbackend/clip.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package goglbackend
import (
"unsafe"

"github.com/tfriedel6/canvas/backend/backendbase"
"github.com/tfriedel6/canvas/backend/goglbackend/gl"
)

Expand All @@ -13,7 +14,7 @@ func (b *GoGLBackend) ClearClip() {
gl.Clear(gl.STENCIL_BUFFER_BIT)
}

func (b *GoGLBackend) Clip(pts [][2]float64) {
func (b *GoGLBackend) Clip(pts []backendbase.Vec) {
b.activate()

b.ptsBuf = b.ptsBuf[:0]
Expand Down
10 changes: 5 additions & 5 deletions backend/goglbackend/fill.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"github.com/tfriedel6/canvas/backend/goglbackend/gl"
)

func (b *GoGLBackend) Clear(pts [4][2]float64) {
func (b *GoGLBackend) Clear(pts [4]backendbase.Vec) {
b.activate()

// first check if the four points are aligned to form a nice rectangle, which can be more easily
Expand Down Expand Up @@ -71,7 +71,7 @@ func (b *GoGLBackend) clearRect(x, y, w, h int) {
gl.Disable(gl.SCISSOR_TEST)
}

func extent(pts [][2]float64) (min, max vec) {
func extent(pts []backendbase.Vec) (min, max backendbase.Vec) {
max[0] = -math.MaxFloat64
max[1] = -math.MaxFloat64
min[0] = math.MaxFloat64
Expand All @@ -85,7 +85,7 @@ func extent(pts [][2]float64) (min, max vec) {
return
}

func (b *GoGLBackend) Fill(style *backendbase.FillStyle, pts [][2]float64, canOverlap bool) {
func (b *GoGLBackend) Fill(style *backendbase.FillStyle, pts []backendbase.Vec, canOverlap bool) {
b.activate()

if style.Blur > 0 {
Expand Down Expand Up @@ -164,7 +164,7 @@ func (b *GoGLBackend) Fill(style *backendbase.FillStyle, pts [][2]float64, canOv
}
}

func (b *GoGLBackend) FillImageMask(style *backendbase.FillStyle, mask *image.Alpha, pts [4][2]float64) {
func (b *GoGLBackend) FillImageMask(style *backendbase.FillStyle, mask *image.Alpha, pts [4]backendbase.Vec) {
b.activate()

w, h := mask.Rect.Dx(), mask.Rect.Dy()
Expand Down Expand Up @@ -226,7 +226,7 @@ func (b *GoGLBackend) FillImageMask(style *backendbase.FillStyle, mask *image.Al
}
}

func (b *GoGLBackend) drawBlurred(size float64, min, max vec) {
func (b *GoGLBackend) drawBlurred(size float64, min, max backendbase.Vec) {
b.offscr1.alpha = true
b.offscr2.alpha = true

Expand Down
31 changes: 7 additions & 24 deletions backend/goglbackend/gogl.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package goglbackend

import (
"fmt"
"math"

"github.com/tfriedel6/canvas/backend/backendbase"
"github.com/tfriedel6/canvas/backend/goglbackend/gl"
Expand Down Expand Up @@ -274,11 +273,11 @@ func (b *GoGLBackend) useShader(style *backendbase.FillStyle, useAlpha bool, alp
lg := lg.(*LinearGradient)
gl.ActiveTexture(gl.TEXTURE0)
gl.BindTexture(gl.TEXTURE_2D, lg.tex)
from := vec{style.Gradient.X0, style.Gradient.Y0}
to := vec{style.Gradient.X1, style.Gradient.Y1}
dir := to.sub(from)
length := dir.len()
dir = dir.scale(1 / length)
from := backendbase.Vec{style.Gradient.X0, style.Gradient.Y0}
to := backendbase.Vec{style.Gradient.X1, style.Gradient.Y1}
dir := to.Sub(from)
length := dir.Len()
dir = dir.Mulf(1 / length)
gl.Uniform2f(b.shd.From, float32(from[0]), float32(from[1]))
gl.Uniform2f(b.shd.Dir, float32(dir[0]), float32(dir[1]))
gl.Uniform1f(b.shd.Len, float32(length))
Expand All @@ -290,10 +289,8 @@ func (b *GoGLBackend) useShader(style *backendbase.FillStyle, useAlpha bool, alp
rg := rg.(*RadialGradient)
gl.ActiveTexture(gl.TEXTURE0)
gl.BindTexture(gl.TEXTURE_2D, rg.tex)
from := vec{style.Gradient.X0, style.Gradient.Y0}
to := vec{style.Gradient.X1, style.Gradient.Y1}
gl.Uniform2f(b.shd.From, float32(from[0]), float32(from[1]))
gl.Uniform2f(b.shd.To, float32(to[0]), float32(to[1]))
gl.Uniform2f(b.shd.From, float32(style.Gradient.X0), float32(style.Gradient.Y0))
gl.Uniform2f(b.shd.To, float32(style.Gradient.X1), float32(style.Gradient.Y1))
gl.Uniform1f(b.shd.RadFrom, float32(style.Gradient.RadFrom))
gl.Uniform1f(b.shd.RadTo, float32(style.Gradient.RadTo))
gl.Uniform1i(b.shd.Gradient, 0)
Expand Down Expand Up @@ -385,17 +382,3 @@ func (b *GoGLBackend) enableTextureRenderTarget(offscr *offscreenBuffer) {

gl.Clear(gl.COLOR_BUFFER_BIT | gl.STENCIL_BUFFER_BIT)
}

type vec [2]float64

func (v vec) sub(v2 vec) vec {
return vec{v[0] - v2[0], v[1] - v2[1]}
}

func (v vec) len() float64 {
return math.Sqrt(v[0]*v[0] + v[1]*v[1])
}

func (v vec) scale(f float64) vec {
return vec{v[0] * f, v[1] * f}
}
2 changes: 1 addition & 1 deletion backend/goglbackend/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ func (img *Image) Replace(src image.Image) error {
return nil
}

func (b *GoGLBackend) DrawImage(dimg backendbase.Image, sx, sy, sw, sh float64, pts [4][2]float64, alpha float64) {
func (b *GoGLBackend) DrawImage(dimg backendbase.Image, sx, sy, sw, sh float64, pts [4]backendbase.Vec, alpha float64) {
b.activate()

img := dimg.(*Image)
Expand Down
26 changes: 13 additions & 13 deletions backend/softwarebackend/fill.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import (
"github.com/tfriedel6/canvas/backend/backendbase"
)

func (b *SoftwareBackend) Clear(pts [4][2]float64) {
iterateTriangles(pts[:], func(tri [][2]float64) {
func (b *SoftwareBackend) Clear(pts [4]backendbase.Vec) {
iterateTriangles(pts[:], func(tri []backendbase.Vec) {
b.fillTriangleNoAA(tri, func(x, y int) {
if b.clip.AlphaAt(x, y).A == 0 {
return
Expand All @@ -19,7 +19,7 @@ func (b *SoftwareBackend) Clear(pts [4][2]float64) {
})
}

func (b *SoftwareBackend) Fill(style *backendbase.FillStyle, pts [][2]float64, canOverlap bool) {
func (b *SoftwareBackend) Fill(style *backendbase.FillStyle, pts []backendbase.Vec, canOverlap bool) {
ffn := fillFunc(style)

if style.Blur > 0 {
Expand All @@ -31,7 +31,7 @@ func (b *SoftwareBackend) Fill(style *backendbase.FillStyle, pts [][2]float64, c
}
}

func (b *SoftwareBackend) FillImageMask(style *backendbase.FillStyle, mask *image.Alpha, pts [4][2]float64) {
func (b *SoftwareBackend) FillImageMask(style *backendbase.FillStyle, mask *image.Alpha, pts [4]backendbase.Vec) {
ffn := fillFunc(style)

mw := float64(mask.Bounds().Dx())
Expand All @@ -51,24 +51,24 @@ func (b *SoftwareBackend) FillImageMask(style *backendbase.FillStyle, mask *imag
func fillFunc(style *backendbase.FillStyle) func(x, y float64) color.RGBA {
if lg := style.LinearGradient; lg != nil {
lg := lg.(*LinearGradient)
from := [2]float64{style.Gradient.X0, style.Gradient.Y0}
dir := [2]float64{style.Gradient.X1 - style.Gradient.X0, style.Gradient.Y1 - style.Gradient.Y0}
from := backendbase.Vec{style.Gradient.X0, style.Gradient.Y0}
dir := backendbase.Vec{style.Gradient.X1 - style.Gradient.X0, style.Gradient.Y1 - style.Gradient.Y0}
dirlen := math.Sqrt(dir[0]*dir[0] + dir[1]*dir[1])
dir[0] /= dirlen
dir[1] /= dirlen
return func(x, y float64) color.RGBA {
pos := [2]float64{x - from[0], y - from[1]}
pos := backendbase.Vec{x - from[0], y - from[1]}
r := (pos[0]*dir[0] + pos[1]*dir[1]) / dirlen
return lg.data.ColorAt(r)
}
} else if rg := style.RadialGradient; rg != nil {
rg := rg.(*RadialGradient)
from := [2]float64{style.Gradient.X0, style.Gradient.Y0}
to := [2]float64{style.Gradient.X1, style.Gradient.Y1}
from := backendbase.Vec{style.Gradient.X0, style.Gradient.Y0}
to := backendbase.Vec{style.Gradient.X1, style.Gradient.Y1}
radFrom := style.Gradient.RadFrom
radTo := style.Gradient.RadTo
return func(x, y float64) color.RGBA {
pos := [2]float64{x, y}
pos := backendbase.Vec{x, y}
oa := 0.5 * math.Sqrt(
math.Pow(-2.0*from[0]*from[0]+2.0*from[0]*to[0]+2.0*from[0]*pos[0]-2.0*to[0]*pos[0]-2.0*from[1]*from[1]+2.0*from[1]*to[1]+2.0*from[1]*pos[1]-2.0*to[1]*pos[1]+2.0*radFrom*radFrom-2.0*radFrom*radTo, 2.0)-
4.0*(from[0]*from[0]-2.0*from[0]*pos[0]+pos[0]*pos[0]+from[1]*from[1]-2.0*from[1]*pos[1]+pos[1]*pos[1]-radFrom*radFrom)*
Expand All @@ -92,7 +92,7 @@ func fillFunc(style *backendbase.FillStyle) func(x, y float64) color.RGBA {
rx := ip.data.Repeat == backendbase.Repeat || ip.data.Repeat == backendbase.RepeatX
ry := ip.data.Repeat == backendbase.Repeat || ip.data.Repeat == backendbase.RepeatY
return func(x, y float64) color.RGBA {
pos := [2]float64{x, y}
pos := backendbase.Vec{x, y}
tfptx := pos[0]*ip.data.Transform[0] + pos[1]*ip.data.Transform[1] + ip.data.Transform[2]
tfpty := pos[0]*ip.data.Transform[3] + pos[1]*ip.data.Transform[4] + ip.data.Transform[5]

Expand Down Expand Up @@ -134,10 +134,10 @@ func (b *SoftwareBackend) ClearClip() {
}
}

func (b *SoftwareBackend) Clip(pts [][2]float64) {
func (b *SoftwareBackend) Clip(pts []backendbase.Vec) {
b.clearStencil()

iterateTriangles(pts[:], func(tri [][2]float64) {
iterateTriangles(pts[:], func(tri []backendbase.Vec) {
b.fillTriangleNoAA(tri, func(x, y int) {
b.stencil.SetAlpha(x, y, color.Alpha{A: 255})
})
Expand Down
2 changes: 1 addition & 1 deletion backend/softwarebackend/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func halveImage(img image.Image) (*image.RGBA, int, int) {
return rimg, w, h
}

func (b *SoftwareBackend) DrawImage(dimg backendbase.Image, sx, sy, sw, sh float64, pts [4][2]float64, alpha float64) {
func (b *SoftwareBackend) DrawImage(dimg backendbase.Image, sx, sy, sw, sh float64, pts [4]backendbase.Vec, alpha float64) {
simg := dimg.(*Image)
if simg.deleted {
return
Expand Down
50 changes: 26 additions & 24 deletions backend/softwarebackend/triangles.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ package softwarebackend
import (
"image/color"
"math"

"github.com/tfriedel6/canvas/backend/backendbase"
)

func triangleLR(tri [][2]float64, y float64) (l, r float64, outside bool) {
func triangleLR(tri []backendbase.Vec, y float64) (l, r float64, outside bool) {
a, b, c := tri[0], tri[1], tri[2]

// sort by y
Expand Down Expand Up @@ -46,7 +48,7 @@ func triangleLR(tri [][2]float64, y float64) (l, r float64, outside bool) {
return
}

func (b *SoftwareBackend) fillTriangleNoAA(tri [][2]float64, fn func(x, y int)) {
func (b *SoftwareBackend) fillTriangleNoAA(tri []backendbase.Vec, fn func(x, y int)) {
minY := int(math.Floor(math.Min(math.Min(tri[0][1], tri[1][1]), tri[2][1])))
maxY := int(math.Ceil(math.Max(math.Max(tri[0][1], tri[1][1]), tri[2][1])))
if minY < 0 {
Expand Down Expand Up @@ -94,7 +96,7 @@ type msaaPixel struct {
tx, ty float64
}

func (b *SoftwareBackend) fillTriangleMSAA(tri [][2]float64, msaaLevel int, msaaPixels []msaaPixel, fn func(x, y int)) []msaaPixel {
func (b *SoftwareBackend) fillTriangleMSAA(tri []backendbase.Vec, msaaLevel int, msaaPixels []msaaPixel, fn func(x, y int)) []msaaPixel {
msaaStep := 1.0 / float64(msaaLevel+1)

minY := int(math.Floor(math.Min(math.Min(tri[0][1], tri[1][1]), tri[2][1])))
Expand Down Expand Up @@ -194,13 +196,13 @@ func addMSAAPixel(msaaPixels []msaaPixel, px msaaPixel) []msaaPixel {
return append(msaaPixels, px)
}

func quadArea(quad [4][2]float64) float64 {
leftv := [2]float64{quad[1][0] - quad[0][0], quad[1][1] - quad[0][1]}
topv := [2]float64{quad[3][0] - quad[0][0], quad[3][1] - quad[0][1]}
func quadArea(quad [4]backendbase.Vec) float64 {
leftv := backendbase.Vec{quad[1][0] - quad[0][0], quad[1][1] - quad[0][1]}
topv := backendbase.Vec{quad[3][0] - quad[0][0], quad[3][1] - quad[0][1]}
return math.Abs(leftv[0]*topv[1] - leftv[1]*topv[0])
}

func (b *SoftwareBackend) fillQuadNoAA(quad [4][2]float64, fn func(x, y int, tx, ty float64)) {
func (b *SoftwareBackend) fillQuadNoAA(quad [4]backendbase.Vec, fn func(x, y int, tx, ty float64)) {
minY := int(math.Floor(math.Min(math.Min(quad[0][1], quad[1][1]), math.Min(quad[2][1], quad[3][1]))))
maxY := int(math.Ceil(math.Max(math.Max(quad[0][1], quad[1][1]), math.Max(quad[2][1], quad[3][1]))))
if minY < 0 {
Expand All @@ -214,17 +216,17 @@ func (b *SoftwareBackend) fillQuadNoAA(quad [4][2]float64, fn func(x, y int, tx,
maxY = b.h - 1
}

leftv := [2]float64{quad[1][0] - quad[0][0], quad[1][1] - quad[0][1]}
leftv := backendbase.Vec{quad[1][0] - quad[0][0], quad[1][1] - quad[0][1]}
leftLen := math.Sqrt(leftv[0]*leftv[0] + leftv[1]*leftv[1])
leftv[0] /= leftLen
leftv[1] /= leftLen
topv := [2]float64{quad[3][0] - quad[0][0], quad[3][1] - quad[0][1]}
topv := backendbase.Vec{quad[3][0] - quad[0][0], quad[3][1] - quad[0][1]}
topLen := math.Sqrt(topv[0]*topv[0] + topv[1]*topv[1])
topv[0] /= topLen
topv[1] /= topLen

tri1 := [3][2]float64{quad[0], quad[1], quad[2]}
tri2 := [3][2]float64{quad[0], quad[2], quad[3]}
tri1 := [3]backendbase.Vec{quad[0], quad[1], quad[2]}
tri2 := [3]backendbase.Vec{quad[0], quad[2], quad[3]}
for y := minY; y <= maxY; y++ {
lf1, rf1, out1 := triangleLR(tri1[:], float64(y)+0.5)
lf2, rf2, out2 := triangleLR(tri2[:], float64(y)+0.5)
Expand Down Expand Up @@ -270,7 +272,7 @@ func (b *SoftwareBackend) fillQuadNoAA(quad [4][2]float64, fn func(x, y int, tx,
}
}

func (b *SoftwareBackend) fillQuadMSAA(quad [4][2]float64, msaaLevel int, msaaPixels []msaaPixel, fn func(x, y int, tx, ty float64)) []msaaPixel {
func (b *SoftwareBackend) fillQuadMSAA(quad [4]backendbase.Vec, msaaLevel int, msaaPixels []msaaPixel, fn func(x, y int, tx, ty float64)) []msaaPixel {
msaaStep := 1.0 / float64(msaaLevel+1)

minY := int(math.Floor(math.Min(math.Min(quad[0][1], quad[1][1]), math.Min(quad[2][1], quad[3][1]))))
Expand All @@ -286,17 +288,17 @@ func (b *SoftwareBackend) fillQuadMSAA(quad [4][2]float64, msaaLevel int, msaaPi
maxY = b.h - 1
}

leftv := [2]float64{quad[1][0] - quad[0][0], quad[1][1] - quad[0][1]}
leftv := backendbase.Vec{quad[1][0] - quad[0][0], quad[1][1] - quad[0][1]}
leftLen := math.Sqrt(leftv[0]*leftv[0] + leftv[1]*leftv[1])
leftv[0] /= leftLen
leftv[1] /= leftLen
topv := [2]float64{quad[3][0] - quad[0][0], quad[3][1] - quad[0][1]}
topv := backendbase.Vec{quad[3][0] - quad[0][0], quad[3][1] - quad[0][1]}
topLen := math.Sqrt(topv[0]*topv[0] + topv[1]*topv[1])
topv[0] /= topLen
topv[1] /= topLen

tri1 := [3][2]float64{quad[0], quad[1], quad[2]}
tri2 := [3][2]float64{quad[0], quad[2], quad[3]}
tri1 := [3]backendbase.Vec{quad[0], quad[1], quad[2]}
tri2 := [3]backendbase.Vec{quad[0], quad[2], quad[3]}
for y := minY; y <= maxY; y++ {
var l, r [5]float64
allOut := true
Expand Down Expand Up @@ -400,7 +402,7 @@ func (b *SoftwareBackend) fillQuadMSAA(quad [4][2]float64, msaaLevel int, msaaPi
return msaaPixels
}

func (b *SoftwareBackend) fillQuad(pts [4][2]float64, fn func(x, y, tx, ty float64) color.RGBA) {
func (b *SoftwareBackend) fillQuad(pts [4]backendbase.Vec, fn func(x, y, tx, ty float64) color.RGBA) {
b.clearStencil()

if b.MSAA > 0 {
Expand Down Expand Up @@ -470,9 +472,9 @@ func (b *SoftwareBackend) fillQuad(pts [4][2]float64, fn func(x, y, tx, ty float
}
}

func iterateTriangles(pts [][2]float64, fn func(tri [][2]float64)) {
func iterateTriangles(pts []backendbase.Vec, fn func(tri []backendbase.Vec)) {
if len(pts) == 4 {
var buf [3][2]float64
var buf [3]backendbase.Vec
buf[0] = pts[0]
buf[1] = pts[1]
buf[2] = pts[2]
Expand All @@ -487,8 +489,8 @@ func iterateTriangles(pts [][2]float64, fn func(tri [][2]float64)) {
}
}

func (b *SoftwareBackend) fillTrianglesNoAA(pts [][2]float64, fn func(x, y float64) color.RGBA) {
iterateTriangles(pts[:], func(tri [][2]float64) {
func (b *SoftwareBackend) fillTrianglesNoAA(pts []backendbase.Vec, fn func(x, y float64) color.RGBA) {
iterateTriangles(pts[:], func(tri []backendbase.Vec) {
b.fillTriangleNoAA(tri, func(x, y int) {
if b.clip.AlphaAt(x, y).A == 0 {
return
Expand All @@ -505,11 +507,11 @@ func (b *SoftwareBackend) fillTrianglesNoAA(pts [][2]float64, fn func(x, y float
})
}

func (b *SoftwareBackend) fillTrianglesMSAA(pts [][2]float64, msaaLevel int, fn func(x, y float64) color.RGBA) {
func (b *SoftwareBackend) fillTrianglesMSAA(pts []backendbase.Vec, msaaLevel int, fn func(x, y float64) color.RGBA) {
var msaaPixelBuf [500]msaaPixel
msaaPixels := msaaPixelBuf[:0]

iterateTriangles(pts[:], func(tri [][2]float64) {
iterateTriangles(pts[:], func(tri []backendbase.Vec) {
msaaPixels = b.fillTriangleMSAA(tri, msaaLevel, msaaPixels, func(x, y int) {
if b.clip.AlphaAt(x, y).A == 0 {
return
Expand Down Expand Up @@ -558,7 +560,7 @@ func (b *SoftwareBackend) fillTrianglesMSAA(pts [][2]float64, msaaLevel int, fn
}
}

func (b *SoftwareBackend) fillTriangles(pts [][2]float64, fn func(x, y float64) color.RGBA) {
func (b *SoftwareBackend) fillTriangles(pts []backendbase.Vec, fn func(x, y float64) color.RGBA) {
b.clearStencil()

if b.MSAA > 0 {
Expand Down
Loading

0 comments on commit 804a9c2

Please sign in to comment.